Merge lp:~fabien-morin/unifield-server/fm-us-2619 into lp:unifield-server
- fm-us-2619
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4783 |
Proposed branch: | lp:~fabien-morin/unifield-server/fm-us-2619 |
Merge into: | lp:unifield-server |
Diff against target: |
2941 lines (+2211/-110) 18 files modified
bin/addons/account_hq_entries/wizard/hq_entries_import.py (+9/-4) bin/addons/base/ir/ir_actions.py (+1/-1) bin/addons/import_data/import_data.py (+4/-1) bin/addons/msf_budget/wizard/wizard_budget_import.py (+3/-0) bin/addons/msf_doc_import/__init__.py (+1/-0) bin/addons/msf_doc_import/__openerp__.py (+1/-0) bin/addons/msf_doc_import/doc_import_report.xml (+11/-0) bin/addons/msf_doc_import/msf_import_export.py (+853/-0) bin/addons/msf_doc_import/msf_import_export_conf.py (+579/-0) bin/addons/msf_doc_import/report/export_generic.mako (+137/-0) bin/addons/msf_doc_import/report/import_generic_template.mako (+21/-0) bin/addons/msf_doc_import/report/import_generic_template.py (+52/-0) bin/addons/msf_doc_import/view/msf_import_export_view.xml (+99/-0) bin/addons/msf_doc_import/wizard/abstract_wizard_import.py (+28/-3) bin/addons/msf_profile/i18n/fr_MF.po (+395/-96) bin/addons/product_nomenclature/product_nomenclature.py (+1/-1) bin/addons/res_currency_tables/wizard/import_currencies.py (+4/-0) bin/osv/orm.py (+12/-4) |
To merge this branch: | bzr merge lp:~fabien-morin/unifield-server/fm-us-2619 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+322034@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Jeff Allen (jr.allen) : | # |
Revision history for this message
Fabien MORIN (fabien-morin) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/account_hq_entries/wizard/hq_entries_import.py' |
2 | --- bin/addons/account_hq_entries/wizard/hq_entries_import.py 2017-02-28 16:07:39 +0000 |
3 | +++ bin/addons/account_hq_entries/wizard/hq_entries_import.py 2017-09-27 13:17:20 +0000 |
4 | @@ -291,6 +291,9 @@ |
5 | if not context: |
6 | context = {} |
7 | |
8 | + if isinstance(ids, (int, long)): |
9 | + ids = [ids] |
10 | + |
11 | # Verify that an HQ journal exists |
12 | journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'hq'), |
13 | ('is_current_instance', '=', True)]) |
14 | @@ -314,18 +317,20 @@ |
15 | errors.append('Line %s, %s' % (line_index, _(msg))) |
16 | |
17 | # Browse all given wizard |
18 | - for wiz in self.browse(cr, uid, ids): |
19 | - if not wiz.file: |
20 | + read_result = self.read(cr, uid, ids, ['file', 'filename'], |
21 | + context=context) |
22 | + for wiz in read_result: |
23 | + if not wiz['file']: |
24 | raise osv.except_osv(_('Error'), _('Nothing to import.')) |
25 | # Decode file string |
26 | fileobj = NamedTemporaryFile('w+') |
27 | - fileobj.write(decodestring(wiz.file)) |
28 | + fileobj.write(decodestring(wiz['file'])) |
29 | # now we determine the file format |
30 | fileobj.seek(0) |
31 | # Read CSV file |
32 | try: |
33 | reader = csv.reader(fileobj, delimiter=',', quotechar='"') |
34 | - filename = wiz.filename or "" |
35 | + filename = wiz['filename'] or "" |
36 | except: |
37 | fileobj.close() |
38 | raise osv.except_osv(_('Error'), _('Problem to read given file.')) |
39 | |
40 | === modified file 'bin/addons/base/ir/ir_actions.py' |
41 | --- bin/addons/base/ir/ir_actions.py 2017-05-18 12:16:12 +0000 |
42 | +++ bin/addons/base/ir/ir_actions.py 2017-09-27 13:17:20 +0000 |
43 | @@ -150,7 +150,7 @@ |
44 | _name = 'ir.actions.act_window' |
45 | _table = 'ir_act_window' |
46 | _sequence = 'ir_actions_id_seq' |
47 | - _order = 'name' |
48 | + _order = 'name, id' |
49 | _replace_exported_fields = { |
50 | 'groups_txt': [ |
51 | (['groups_id', 'Groups'], 10) |
52 | |
53 | === modified file 'bin/addons/import_data/import_data.py' |
54 | --- bin/addons/import_data/import_data.py 2016-05-24 08:44:23 +0000 |
55 | +++ bin/addons/import_data/import_data.py 2017-09-27 13:17:20 +0000 |
56 | @@ -46,7 +46,10 @@ |
57 | |
58 | if data.get('parent_id', False): |
59 | n_obj = self.pool.get('product.nomenclature') |
60 | - parent_ids = n_obj.search(cr, uid, [('msfid', '=', data['parent_id'])], limit=1) |
61 | + if isinstance(data['parent_id'], (int, long)): |
62 | + parent_ids = [data['parent_id']] |
63 | + else: |
64 | + parent_ids = n_obj.search(cr, uid, [('msfid', '=', data['parent_id'])], limit=1) |
65 | if parent_ids: |
66 | parent_id = parent_ids[0] |
67 | |
68 | |
69 | === modified file 'bin/addons/msf_budget/wizard/wizard_budget_import.py' |
70 | --- bin/addons/msf_budget/wizard/wizard_budget_import.py 2015-08-06 14:08:20 +0000 |
71 | +++ bin/addons/msf_budget/wizard/wizard_budget_import.py 2017-09-27 13:17:20 +0000 |
72 | @@ -216,6 +216,9 @@ |
73 | if context is None: |
74 | context = {} |
75 | |
76 | + if isinstance(ids, (int, long)): |
77 | + ids = [ids] |
78 | + |
79 | # Prepare some values |
80 | budgets_2be_approved = {} |
81 | tool_obj = self.pool.get('msf.budget.tools') |
82 | |
83 | === modified file 'bin/addons/msf_doc_import/__init__.py' |
84 | --- bin/addons/msf_doc_import/__init__.py 2016-05-17 12:05:25 +0000 |
85 | +++ bin/addons/msf_doc_import/__init__.py 2017-09-27 13:17:20 +0000 |
86 | @@ -54,3 +54,4 @@ |
87 | import product_list |
88 | import supplier_catalogue |
89 | import report |
90 | +import msf_import_export |
91 | |
92 | === modified file 'bin/addons/msf_doc_import/__openerp__.py' |
93 | --- bin/addons/msf_doc_import/__openerp__.py 2017-05-22 16:04:34 +0000 |
94 | +++ bin/addons/msf_doc_import/__openerp__.py 2017-09-27 13:17:20 +0000 |
95 | @@ -51,6 +51,7 @@ |
96 | 'view/stock_picking_import_lines_view.xml', |
97 | 'view/replenishment_rules_view.xml', |
98 | 'view/supplier_catalogue_view.xml', |
99 | + 'view/msf_import_export_view.xml', |
100 | 'wizard/wizard_import_po_line_view.xml', |
101 | 'wizard/wizard_import_fo_line.xml', |
102 | 'wizard/wizard_import_tender_line.xml', |
103 | |
104 | === modified file 'bin/addons/msf_doc_import/doc_import_report.xml' |
105 | --- bin/addons/msf_doc_import/doc_import_report.xml 2016-07-27 08:54:22 +0000 |
106 | +++ bin/addons/msf_doc_import/doc_import_report.xml 2017-09-27 13:17:20 +0000 |
107 | @@ -45,5 +45,16 @@ |
108 | auto="False" |
109 | string="Import Generic template" /> |
110 | |
111 | + <report |
112 | + id="wizard_export_generic" |
113 | + model="msf.import.export" |
114 | + name="wizard.export.generic" |
115 | + file="msf_doc_import/report/export_generic.mako" |
116 | + report_type="webkit" |
117 | + header="False" |
118 | + menu="False" |
119 | + auto="False" |
120 | + string="Generic Export" /> |
121 | + |
122 | </data> |
123 | </openerp> |
124 | |
125 | === added file 'bin/addons/msf_doc_import/msf_import_export.py' |
126 | --- bin/addons/msf_doc_import/msf_import_export.py 1970-01-01 00:00:00 +0000 |
127 | +++ bin/addons/msf_doc_import/msf_import_export.py 2017-09-27 13:17:20 +0000 |
128 | @@ -0,0 +1,853 @@ |
129 | +# encoding: utf-8 |
130 | +############################################################################## |
131 | +# |
132 | +# OpenERP, Open Source Management Solution |
133 | +# Copyright (C) 2017 MSF, TeMPO Consulting |
134 | +# |
135 | +# This program is free software: you can redistribute it and/or modify |
136 | +# it under the terms of the GNU General Public License as published by |
137 | +# the Free Software Foundation, either version 3 of the License, or |
138 | +# (at your option) any later version. |
139 | +# |
140 | +# This program is distributed in the hope that it will be useful, |
141 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
142 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
143 | +# GNU General Public License for more details. |
144 | +# |
145 | +# You should have received a copy of the GNU General Public License |
146 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
147 | +# |
148 | +############################################################################## |
149 | + |
150 | +import base64 |
151 | +import time |
152 | +import threading |
153 | +import logging |
154 | + |
155 | +import pooler |
156 | +import tools |
157 | + |
158 | +from osv import fields |
159 | +from osv import osv |
160 | +from tools.translate import _ |
161 | + |
162 | +from tempfile import TemporaryFile |
163 | +from lxml import etree |
164 | +from lxml.etree import XMLSyntaxError |
165 | + |
166 | +from msf_doc_import.wizard.abstract_wizard_import import ImportHeader |
167 | +from msf_doc_import.msf_import_export_conf import MODEL_DICT |
168 | +from msf_doc_import.msf_import_export_conf import MODEL_DATA_DICT |
169 | + |
170 | +MIN_COLUMN_SIZE = 40 |
171 | +MAX_COLUMN_SIZE = 400 |
172 | + |
173 | +MODEL_HEADER_NOT_CHECKED = ['user.access.configurator', 'hr.employee', 'hq.entries', 'msf.budget'] |
174 | + |
175 | +class msf_import_export(osv.osv_memory): |
176 | + _name = 'msf.import.export' |
177 | + _description = 'MSF Import Export' |
178 | + _inherit = 'abstract.wizard.import' |
179 | + |
180 | + def _get_model_list(self, cr, uid, context=None): |
181 | + """The list of available model depend on the menu entry selected |
182 | + """ |
183 | + if context is None: |
184 | + context = {} |
185 | + domain_type = None |
186 | + if 'domain_type' in context: |
187 | + domain_type = context['domain_type'] |
188 | + result_list = [(key, _(value['name'])) for key, value in MODEL_DICT.items() if value['domain_type'] == domain_type] |
189 | + return [('', '')] + sorted(result_list, key=lambda a: a[0]) |
190 | + |
191 | + _columns = { |
192 | + 'display_file_import': fields.boolean('File Import'), |
193 | + 'display_file_export': fields.boolean('File Export'), |
194 | + 'model_list_selection': fields.selection(selection=_get_model_list, string='Object to Import/Export', required=True), |
195 | + 'import_file': fields.binary('File to import .xml'), |
196 | + 'hide_download_3_entries': fields.boolean('Hide export 3 entries button'), |
197 | + 'hide_download_all_entries': fields.boolean('Hide export all entries button'), |
198 | + 'display_import_buttons': fields.boolean('Display import buttons'), |
199 | + 'csv_button': fields.boolean('Import from CSV'), |
200 | + } |
201 | + |
202 | + _default = { |
203 | + 'display_file_import': lambda *a: False, |
204 | + 'display_file_export': lambda *a: False, |
205 | + 'hide_download_3_entries': lambda *a: False, |
206 | + 'hide_download_all_entries': lambda *a: False, |
207 | + 'display_import_buttons': lambda *a: False, |
208 | + 'csv_button': lambda *a: False, |
209 | + } |
210 | + |
211 | + def get_filename(self, cr, uid, model, selection, template_only=False, context=None): |
212 | + """Generate a filename for the import/export |
213 | + """ |
214 | + model_obj = self.pool.get(model) |
215 | + file_name = _(MODEL_DICT[selection]['name']) |
216 | + file_name = file_name.replace(' ', '_') |
217 | + if template_only: |
218 | + file_name = _('%s_Import_Template') % file_name |
219 | + else: |
220 | + file_name = _('%s_Export_%s') % (file_name, time.strftime('%Y%m%d')) |
221 | + return file_name |
222 | + |
223 | + def generic_download(self, cr, uid, ids, template_only=False, |
224 | + nb_lines=None, context=None): |
225 | + """Mutualise the code of all download buttons in one place |
226 | + """ |
227 | + if context is None: |
228 | + context = {} |
229 | + if isinstance(ids, (int, long)): |
230 | + ids = [ids] |
231 | + |
232 | + wiz = self.browse(cr, uid, ids[0]) |
233 | + selection = wiz.model_list_selection |
234 | + model = MODEL_DICT[selection]['model'] |
235 | + if selection not in MODEL_DATA_DICT: |
236 | + raise osv.except_osv(_('Error'), |
237 | + _('Selection \'%s\' not found. ' |
238 | + 'Please contact the support team.') % (selection)) |
239 | + |
240 | + if 'header_list' not in MODEL_DATA_DICT[selection]: |
241 | + raise osv.except_osv(_('Error'), |
242 | + _('The header_list for report \'%s\' is not' |
243 | + ' defined. Please contact the support team.') % (selection)) |
244 | + fields = MODEL_DATA_DICT[selection]['header_list'] |
245 | + domain = MODEL_DICT[selection].get('domain', []) |
246 | + context['translate_selection_field'] = True |
247 | + data = { |
248 | + 'model': model, |
249 | + 'fields': fields, |
250 | + 'nb_lines': nb_lines, |
251 | + 'template_only': template_only, |
252 | + 'domain': domain, |
253 | + 'target_filename': self.get_filename(cr, uid, model, selection, template_only), |
254 | + } |
255 | + return { |
256 | + 'type': 'ir.actions.report.xml', |
257 | + 'report_name': 'wizard.export.generic', |
258 | + 'datas': data, |
259 | + 'context': context, |
260 | + } |
261 | + |
262 | + def download_all_entries_file(self, cr, uid, ids, context=None): |
263 | + """Download a template filled with all datas of the modele |
264 | + """ |
265 | + return self.generic_download(cr, uid, ids, context=context) |
266 | + |
267 | + def download_3_entries_file(self, cr, uid, ids, context=None): |
268 | + """Download a template filled with the first 3 lines of data |
269 | + """ |
270 | + return self.generic_download(cr, uid, ids, nb_lines=3, context=context) |
271 | + |
272 | + def download_template_file(self, cr, uid, ids, context=None): |
273 | + """Download the template file (without any data) |
274 | + """ |
275 | + return self.generic_download(cr, uid, ids, template_only=True, |
276 | + context=context) |
277 | + |
278 | + def get_excel_size_from_string(self, string): |
279 | + """Compute the string to get the size of it in a excel |
280 | + understandable value |
281 | + :param string: the str chain to get the excel size |
282 | + :return: A int instance |
283 | + """ |
284 | + # this calculation is used to translate the |
285 | + # character len to an excel understandable len |
286 | + |
287 | + max_digit_width = 7 # For Calabri 11 which is the font used in our reports |
288 | + conversion_factor = 3/4. # to convert from pixel to points |
289 | + padding = 15 |
290 | + |
291 | + # this formule partially come from readings here: |
292 | + # http://stackoverflow.com/questions/4577546/calculating-height-width-and-ysplit-xsplit-for-open-xml-spreadsheets?answertab=votes#tab-top |
293 | + size = round(max_digit_width*len(string)*conversion_factor+padding) |
294 | + |
295 | + # set a max and min len for the columns to avoid ridiculus column size |
296 | + size = min(size, MAX_COLUMN_SIZE) |
297 | + size = max(size, MIN_COLUMN_SIZE) |
298 | + return size |
299 | + |
300 | + def get_child_field(self, cr, uid, field, model, fields_get_dict, |
301 | + context=None): |
302 | + if context is None: |
303 | + context = {} |
304 | + if '.' in field: |
305 | + model_obj = self.pool.get(model) |
306 | + if model not in fields_get_dict: |
307 | + fields_get_res = model_obj.fields_get(cr, uid, context=context) |
308 | + fields_get_dict[model] = fields_get_res |
309 | + else: |
310 | + fields_get_res = fields_get_dict[model] |
311 | + |
312 | + |
313 | + child_field = field.split('.')[0] |
314 | + rest = '.'.join(field.split('.')[1:]) |
315 | + if child_field == 'id': |
316 | + return field, model |
317 | + |
318 | + if child_field not in fields_get_res: |
319 | + raise osv.except_osv(_('Error'), |
320 | + _('field \'%s\' not found for model \'%s\'. Please contact the support team.') |
321 | + % (child_field, model)) |
322 | + |
323 | + #if child and child !='id' and fields_get_res[child_field].get('relation'): |
324 | + child_model = fields_get_res[child_field]['relation'] |
325 | + if child_model not in fields_get_dict: |
326 | + model_obj = self.pool.get(child_model) |
327 | + fields_get_res = model_obj.fields_get(cr, uid, context=context) |
328 | + fields_get_dict[child_model] = fields_get_res |
329 | + return self.get_child_field(cr, uid, rest, child_model, fields_get_dict, |
330 | + context=context) |
331 | + else: |
332 | + return field, model |
333 | + |
334 | + def _get_headers(self, cr, uid, model, selection=None, field_list=None, rows=None, context=None): |
335 | + """Generate a list of ImportHeader objects using the data that retived |
336 | + from the field name. |
337 | + :param model: Model of the object imported/exported |
338 | + :param selection: requried to get the list of fields to compose the header |
339 | + :param field_list: if known, the list of the fields to display in the |
340 | + header can be passed |
341 | + :param rows: Data rows to export. In case of export, the size of the |
342 | + columns matter and can be determinied according to the data string length |
343 | + :param context: Context of the call, this is particularly important to |
344 | + get the language for tranlsating the fields. |
345 | + :return: A list of ImportHeader |
346 | + """ |
347 | + if context is None: |
348 | + context = {} |
349 | + headers = [] |
350 | + if not field_list: |
351 | + field_list = MODEL_DATA_DICT[selection]['header_list'] |
352 | + model_obj = self.pool.get(model) |
353 | + |
354 | + fields_get_dict = {} # keep fields_get result in cache |
355 | + fields_get_dict[model] = model_obj.fields_get(cr, uid, context=context) |
356 | + |
357 | + for field_index, field in enumerate(field_list): |
358 | + res = {'tech_name': field} |
359 | + if selection and field in MODEL_DATA_DICT[selection]['required_field_list']: |
360 | + res['required'] = True |
361 | + child_field, child_model = self.get_child_field(cr, uid, field, model, |
362 | + fields_get_dict, context=context) |
363 | + first_part = field.split('.')[0] |
364 | + if child_field == 'id': |
365 | + res['name'] = '%s / XMLID' % fields_get_dict[model][first_part]['string'] |
366 | + elif first_part not in fields_get_dict[model]: |
367 | + raise osv.except_osv(_('Error'), |
368 | + _('field \'%s\' not found for model \'%s\'. Please contact the support team.') |
369 | + % (first_part, model)) |
370 | + elif first_part != child_field: |
371 | + if child_field not in fields_get_dict[child_model]: |
372 | + raise osv.except_osv(_('Error'), |
373 | + _('field \'%s\' not found for model \'%s\'. Please contact the support team.') |
374 | + % (child_field, child_model)) |
375 | + res['name'] = '%s / %s' % (fields_get_dict[model][first_part]['string'], |
376 | + fields_get_dict[child_model][child_field]['string']) |
377 | + else: |
378 | + res['name'] = fields_get_dict[model][first_part]['string'] |
379 | + |
380 | + |
381 | + if child_field == 'id': |
382 | + field_type == 'String' |
383 | + else: |
384 | + field_type = fields_get_dict[child_model][child_field]['type'] |
385 | + if field_type == 'boolean': |
386 | + res['ftype'] = 'Boolean' |
387 | + elif field_type == 'float': |
388 | + res['ftype'] = 'Float' |
389 | + elif field_type == 'integer': |
390 | + res['ftype'] = 'Number' |
391 | + else: |
392 | + res['ftype'] = 'String' |
393 | + |
394 | + if not rows: |
395 | + # if no data passed, set the column size with the size of the header name |
396 | + res['size'] = self.get_excel_size_from_string(res['name']) |
397 | + else: |
398 | + # automatically set the width of the column by searching for the |
399 | + # biggest string in this column |
400 | + all_cells_chain = [tools.ustr(x[field_index]) for x in rows] |
401 | + res['size'] = MIN_COLUMN_SIZE |
402 | + if all_cells_chain: |
403 | + longest_chain = max(all_cells_chain, key=len) |
404 | + if longest_chain: |
405 | + res['size'] = self.get_excel_size_from_string(longest_chain) |
406 | + headers.append(ImportHeader(**res)) |
407 | + return headers |
408 | + |
409 | + def domain_type_change(self, cr, uid, ids, model_list_selection, context=None): |
410 | + """When the type of object to import/export change, change the buttons |
411 | + to display or not according to the new object model |
412 | + """ |
413 | + if context is None: |
414 | + context = {} |
415 | + result = {'value': {}} |
416 | + result['value']['display_file_import'] = True |
417 | + result['value']['display_file_export'] = True |
418 | + if model_list_selection: |
419 | + if model_list_selection and model_list_selection in MODEL_DATA_DICT: |
420 | + hide_export = MODEL_DATA_DICT[model_list_selection].get('hide_export', False) |
421 | + result['value']['display_file_export'] = not hide_export |
422 | + hide_3 = MODEL_DATA_DICT[model_list_selection].get('hide_download_3_entries', False) |
423 | + result['value']['hide_download_3_entries'] = hide_3 |
424 | + hide_all = MODEL_DATA_DICT[model_list_selection].get('hide_download_all_entries', False) |
425 | + result['value']['hide_download_all_entries'] = hide_all |
426 | + csv_button = MODEL_DATA_DICT[model_list_selection].get('csv_button', False) |
427 | + result['value']['csv_button'] = csv_button |
428 | + else: |
429 | + result['value']['hide_download_3_entries'] = False |
430 | + result['value']['hide_download_all_entries'] = False |
431 | + return result |
432 | + |
433 | + def file_change(self, cr, uid, obj_id, import_file, context=None): |
434 | + """Display the import button only if a file as been selected |
435 | + """ |
436 | + if context is None: |
437 | + context = {} |
438 | + result = {'value': {'display_import_buttons': False}} |
439 | + if import_file: |
440 | + result['value']['display_import_buttons'] = True |
441 | + return result |
442 | + |
443 | + def check_xml_syntax(self, cr, uid, xml_string, context=None): |
444 | + """Try to parse the xml file and raise if there is an error |
445 | + """ |
446 | + try: |
447 | + file_dom = etree.fromstring(xml_string) |
448 | + except XMLSyntaxError as e: |
449 | + raise osv.except_osv(_('Error'), _('File structure is incorrect, ' |
450 | + 'please correct. You may generate a template with the File ' |
451 | + 'export functionality.')) |
452 | + |
453 | + def test_import(self, cr, uid, ids, context=None): |
454 | + """Warn if file structure is correct |
455 | + """ |
456 | + if self.check_import(cr, uid, ids, context=context): |
457 | + raise osv.except_osv(_('Info'), _('File structure is correct.')) |
458 | + |
459 | + def check_import(self, cr, uid, ids, context=None): |
460 | + """Verify that a file has been selected and all columns expected are |
461 | + present |
462 | + """ |
463 | + obj = self.read(cr, uid, ids[0]) |
464 | + if not obj['import_file']: |
465 | + raise osv.except_osv(_('Error'), _('Nothing to import.')) |
466 | + fileobj = TemporaryFile('w+') |
467 | + try: |
468 | + for wiz in self.browse(cr, uid, ids, context=context): |
469 | + selection = wiz.model_list_selection |
470 | + model = MODEL_DICT[selection]['model'] |
471 | + if model in MODEL_HEADER_NOT_CHECKED: |
472 | + continue |
473 | + xml_string = base64.decodestring(obj['import_file']) |
474 | + self.check_xml_syntax(cr, uid, xml_string, context=context) |
475 | + rows, nb_rows = self.read_file(wiz, context=context) |
476 | + head = rows.next() |
477 | + self.check_missing_columns(cr, uid, wiz, head, context=context) |
478 | + finally: |
479 | + fileobj.close() |
480 | + return True |
481 | + |
482 | + def excel_col(self, col): |
483 | + """Covert column number (1,2,...26,27,28...) to excel-style column label |
484 | + letters (A,B,..Z,AA,AB,...).""" |
485 | + quot, rem = divmod(col-1,26) |
486 | + return self.excel_col(quot) + chr(rem+ord('A')) if col!=0 else '' |
487 | + |
488 | + def check_missing_columns(self, cr, uid, wizard_brw, head, context=None): |
489 | + """Check that the column names in the file match the expected property |
490 | + names, raise if any column is missing. |
491 | + """ |
492 | + selection = wizard_brw.model_list_selection |
493 | + model = MODEL_DICT[selection]['model'] |
494 | + model_obj = self.pool.get(model) |
495 | + header_columns = [head[i].data for i in range(0, len(head))] |
496 | + missing_columns = [] |
497 | + field_list = MODEL_DATA_DICT[selection]['header_list'] |
498 | + |
499 | + fields_get_dict = {} # keep fields_get result in cache |
500 | + fields_get_dict[model] = model_obj.fields_get(cr, uid, context=context) |
501 | + fields_get_res = model_obj.fields_get(cr, uid, |
502 | + [x.split('.')[0] for x in field_list], context=context) |
503 | + if len(field_list) != len(header_columns): |
504 | + raise osv.except_osv(_('Info'), _('The number of column is not same ' \ |
505 | + 'than expected (get %s, expected %s). Check your import file and ' \ |
506 | + 'the Object to import/export.') % (len(header_columns), len(field_list))) |
507 | + |
508 | + for field_index, field in enumerate(field_list): |
509 | + child_field, child_model = self.get_child_field(cr, uid, field, model, |
510 | + fields_get_dict, context=context) |
511 | + first_part = field.split('.')[0] |
512 | + if child_field == 'id': |
513 | + column_name = '%s / XMLID' % fields_get_dict[model][first_part]['string'] |
514 | + elif first_part not in fields_get_dict[model]: |
515 | + raise osv.except_osv(_('Error'), |
516 | + _('field \'%s\' not found for model \'%s\'. Please contact the support team.') |
517 | + % (first_part, model)) |
518 | + elif first_part != child_field: |
519 | + if child_field not in fields_get_dict[child_model]: |
520 | + raise osv.except_osv(_('Error'), |
521 | + _('field \'%s\' not found for model \'%s\'. Please contact the support team.') |
522 | + % (child_field, child_model)) |
523 | + column_name = '%s / %s' % (fields_get_dict[model][first_part]['string'], |
524 | + fields_get_dict[child_model][child_field]['string']) |
525 | + else: |
526 | + column_name = fields_get_dict[model][first_part]['string'] |
527 | + |
528 | + if column_name.upper() != header_columns[field_index].upper(): |
529 | + missing_columns.append(_('Column %s: get \'%s\' expected \'%s\'.') |
530 | + % (self.excel_col(field_index+1), header_columns[field_index], column_name)) |
531 | + if missing_columns and model not in MODEL_HEADER_NOT_CHECKED: |
532 | + raise osv.except_osv(_('Info'), _('The following columns ' |
533 | + 'are missing in the imported file:\n%s') % ',\n'.join(missing_columns)) |
534 | + |
535 | + def import_csv(self, cr, uid, ids, context=None): |
536 | + if context is None: |
537 | + context = {} |
538 | + if isinstance(ids, (int, long)): |
539 | + ids = [ids] |
540 | + |
541 | + for wiz in self.browse(cr, uid, ids, context=context): |
542 | + selection = wiz.model_list_selection |
543 | + model = MODEL_DICT[selection]['model'] |
544 | + |
545 | + if model == 'hq.entries': |
546 | + hq_import = self.pool.get('hq.entries.import') |
547 | + vals = {'file': wiz.import_file} |
548 | + wizard_id = hq_import.create(cr, uid, vals, context=context) |
549 | + self.write(cr, uid, [wiz.id], { |
550 | + 'state': 'progress', |
551 | + 'start_date': time.strftime('%Y-%m-%d %H:%M:%S'), |
552 | + 'info_message': _('Import in progress in the specific wizard.'), |
553 | + }, context=context) |
554 | + res = hq_import.button_validate(cr, uid, wizard_id, |
555 | + context=context) |
556 | + elif model == 'msf.budget': |
557 | + budget_import = self.pool.get('wizard.budget.import') |
558 | + vals = {'import_file': wiz.import_file} |
559 | + wizard_id = budget_import.create(cr, uid, vals, context=context) |
560 | + res = budget_import.button_import(cr, uid, wizard_id, |
561 | + context=context) |
562 | + |
563 | + else: |
564 | + raise osv.except_osv(_('Error'), |
565 | + _('The model \'%s\' is not made to be imported in CSV file.\n' |
566 | + 'Please contact the support team.') % (model)) |
567 | + self.write(cr, uid, [wiz.id], { |
568 | + 'state': 'done', |
569 | + 'start_date': time.strftime('%Y-%m-%d %H:%M:%S'), |
570 | + 'info_message': _('Import has been done via the specific wizard. The latter had to give information on the import.'), |
571 | + }, context=context) |
572 | + return res |
573 | + |
574 | + def import_xml(self, cr, uid, ids, context=None): |
575 | + """Create a thread to import the data after import checking |
576 | + """ |
577 | + if context is None: |
578 | + context = {} |
579 | + if isinstance(ids, (int, long)): |
580 | + ids = [ids] |
581 | + |
582 | + self.check_import(cr, uid, ids, context=context) |
583 | + |
584 | + for wiz in self.browse(cr, uid, ids, context=context): |
585 | + rows, nb_rows = self.read_file(wiz, context=context) |
586 | + head = rows.next() |
587 | + selection = wiz.model_list_selection |
588 | + model = MODEL_DICT[selection]['model'] |
589 | + |
590 | + if model == 'user.access.configurator': |
591 | + # special case handling for this one |
592 | + model_obj = self.pool.get(model) |
593 | + wizard_id = model_obj.create(cr, uid, {}, context) |
594 | + model_obj.write(cr, uid, [wizard_id], {'file_to_import_uac': |
595 | + wiz.import_file}, context=context) |
596 | + return model_obj.do_process_uac(cr, uid, [wizard_id], context=context) |
597 | + |
598 | + expected_headers = self._get_headers(cr, uid, model, selection=selection, context=context) |
599 | + if model not in MODEL_HEADER_NOT_CHECKED: |
600 | + self.check_headers(head, expected_headers, context=context) |
601 | + |
602 | + self.write(cr, uid, [wiz.id], { |
603 | + 'total_lines_to_import': nb_rows, |
604 | + 'state': 'progress', |
605 | + 'start_date': time.strftime('%Y-%m-%d %H:%M:%S'), |
606 | + 'info_message': _('Import in progress, please leave this window open and press the button \'Update\' ' |
607 | + 'to show the progression of the import. Otherwise, you can continue to use Unifield'), |
608 | + }, context=context) |
609 | + wiz.total_lines_to_import = nb_rows |
610 | + |
611 | + thread = threading.Thread( |
612 | + target=self.bg_import, |
613 | + args=(cr.dbname, uid, wiz, expected_headers, rows, context), |
614 | + ) |
615 | + thread.start() |
616 | + # for now we don't want background but foreground |
617 | + # in case background is needed, just set a value to wait time |
618 | + wait_time = None |
619 | + thread.join(wait_time) |
620 | + return True |
621 | + |
622 | + def bg_import(self, dbname, uid, import_brw, headers, rows, context=None): |
623 | + """ |
624 | + Run the import of lines in background |
625 | + :param dbname: Name of the database |
626 | + :param uid: ID of the res.users that calls this method |
627 | + :param import_brw: browse_record of a wizard.import.batch |
628 | + :param headers: List of expected headers |
629 | + :param rows: Iterator on file rows |
630 | + :param context: Context of the call |
631 | + :return: True |
632 | + """ |
633 | + if context is None: |
634 | + context = {} |
635 | + cr = pooler.get_db(dbname).cursor() |
636 | + model = MODEL_DICT[import_brw.model_list_selection]['model'] |
637 | + impobj = self.pool.get(model) |
638 | + |
639 | + import_data_obj = self.pool.get('import_data') |
640 | + prod_nomenclature_obj = self.pool.get('product.nomenclature') |
641 | + |
642 | + # Manage errors |
643 | + import_errors = {} |
644 | + |
645 | + def save_error(errors, row_index): |
646 | + if not isinstance(errors, list): |
647 | + errors = [errors] |
648 | + import_errors.setdefault(row_index+2, []) |
649 | + import_errors[row_index+2].extend(errors) |
650 | + |
651 | + # Manage warnings |
652 | + import_warnings = {} |
653 | + |
654 | + def save_warnings(warnings): |
655 | + if not isinstance(warnings, list): |
656 | + warnings = [warnings] |
657 | + import_warnings.setdefault(row_index+2, []) |
658 | + import_warnings[row_index+2].extend(warnings) |
659 | + |
660 | + start_time = time.time() |
661 | + |
662 | + if model == 'product.product': |
663 | + # Create the cache |
664 | + if not hasattr(self, '_cache'): |
665 | + self._cache = {} |
666 | + self._cache.setdefault(dbname, {}) |
667 | + |
668 | + if not hasattr(prod_nomenclature_obj, '_cache'): |
669 | + prod_nomenclature_obj._cache = {} |
670 | + prod_nomenclature_obj._cache.setdefault(dbname, {}) |
671 | + |
672 | + # Clear the cache |
673 | + self._cache[dbname] = {'product.nomenclature': {'name': {}, 'complete_name': {}}, |
674 | + 'product.uom': {'name': {}}, |
675 | + 'product.asset.type': {'name': {}}, |
676 | + 'product.international.status': {'name': {}}, |
677 | + } |
678 | + # Product nomenclature |
679 | + cr.execute('SELECT name, id FROM product_nomenclature;') |
680 | + for nv in cr.dictfetchall(): |
681 | + self._cache[dbname]['product.nomenclature']['name'].update({nv['name']: nv['id']}) |
682 | + # Product category |
683 | + cr.execute('SELECT id, family_id FROM product_category;') |
684 | + for pc in cr.dictfetchall(): |
685 | + prod_nomenclature_obj._cache[dbname].update({pc['family_id']: pc['id']}) |
686 | + # Product nomenclature complete name |
687 | + cr.execute('''SELECT id, name FROM |
688 | +( |
689 | +(SELECT |
690 | + n0.id, n0.name AS name |
691 | +FROM product_nomenclature n0 |
692 | +WHERE n0.level = 0) |
693 | +UNION |
694 | +(SELECT n1.id, n0.name ||' | '|| n1.name AS name |
695 | +FROM product_nomenclature n1 |
696 | + LEFT JOIN product_nomenclature n0 ON n1.parent_id = n0.id |
697 | +WHERE n1.level = 1) |
698 | +UNION |
699 | +(SELECT n2.id, n0.name ||' | '|| n1.name ||' | '|| n2.name AS name |
700 | +FROM product_nomenclature n1 |
701 | + LEFT JOIN product_nomenclature n0 ON n1.parent_id = n0.id |
702 | + LEFT JOIN product_nomenclature n2 ON n2.parent_id = n1.id |
703 | +WHERE n2.level = 2) |
704 | +UNION |
705 | +(SELECT n3.id, n0.name ||' | '|| n1.name ||' | '|| n2.name ||' | '|| n3.name AS name |
706 | +FROM product_nomenclature n1 |
707 | + LEFT JOIN product_nomenclature n0 ON n1.parent_id = n0.id |
708 | + LEFT JOIN product_nomenclature n2 ON n2.parent_id = n1.id |
709 | + LEFT JOIN product_nomenclature n3 ON n3.parent_id = n2.id |
710 | +WHERE n3.level = 3) |
711 | +) AS cn''') |
712 | + for cnv in cr.dictfetchall(): |
713 | + self._cache[dbname]['product.nomenclature']['complete_name'].update({cnv['name']: cnv['id']}) |
714 | + # Product UoM |
715 | + cr.execute('SELECT name, id FROM product_uom;') |
716 | + for uv in cr.dictfetchall(): |
717 | + self._cache[dbname]['product.uom']['name'].update({uv['name']: uv['id']}) |
718 | + # Asset type |
719 | + cr.execute('SELECT name, id FROM product_asset_type;') |
720 | + for av in cr.dictfetchall(): |
721 | + self._cache[dbname]['product.asset.type']['name'].update({av['name']: av['id']}) |
722 | + # International status |
723 | + cr.execute('SELECT name, id FROM product_international_status;') |
724 | + for iv in cr.dictfetchall(): |
725 | + self._cache[dbname]['product.international.status']['name'].update({iv['name']: iv['id']}) |
726 | + |
727 | + fields_def = impobj.fields_get(cr, uid, context=context) |
728 | + i = 0 |
729 | + |
730 | + def _get_obj(header, value, fields_def): |
731 | + list_obj = header.split('.') |
732 | + relation = fields_def[list_obj[0]]['relation'] |
733 | + if impobj._name == 'product.product' and value in self._cache.get(dbname, {}).get(relation, {}).get(list_obj[1], {}): |
734 | + return self._cache[dbname][relation][list_obj[1]][value] |
735 | + new_obj = self.pool.get(relation) |
736 | + if list_obj[1] == 'id': |
737 | + imd_obj = self.pool.get('ir.model.data') |
738 | + |
739 | + if '.' in value: |
740 | + module, xml_id = value.rsplit('.', 1) |
741 | + else: |
742 | + module, xml_id = model, value |
743 | + record_id = imd_obj._get_id(cr, uid, module, xml_id) |
744 | + ir_model_data = imd_obj.read(cr, uid, [record_id], ['res_id']) |
745 | + if not ir_model_data: |
746 | + raise ValueError('No references to %s.%s' % (module, xml_id)) |
747 | + newids = [ir_model_data[0]['res_id']] |
748 | + else: |
749 | + newids = new_obj.search(cr, uid, [(list_obj[1], '=', value)], limit=1) |
750 | + if not newids: |
751 | + # no obj |
752 | + raise osv.except_osv(_('Warning !'), _('%s \'%s\' does not exist') % (new_obj._description, value,)) |
753 | + |
754 | + if impobj._name == 'product.product': |
755 | + self._cache[dbname].setdefault(relation, {}) |
756 | + self._cache[dbname][relation].setdefault(list_obj[1], {}) |
757 | + self._cache[dbname][relation][list_obj[1]][value] = newids[0] |
758 | + return newids[0] |
759 | + |
760 | + def process_data(field, value, fields_def): |
761 | + if value is None or field not in fields_def: |
762 | + return |
763 | + if '.' not in field: |
764 | + if fields_def[field]['type'] == 'selection': |
765 | + if impobj == 'product.product' and self._cache[dbname].get('product.product.%s.%s' % (field, value), False): |
766 | + value = self._cache[dbname]['product.product.%s.%s' % (field, value)] |
767 | + else: |
768 | + for key, val in fields_def[field]['selection']: |
769 | + if value.lower() in [tools.ustr(key).lower(), tools.ustr(val).lower()]: |
770 | + value = key |
771 | + if impobj == 'product.product': |
772 | + self._cache[dbname].setdefault('product.product.%s' % field, {}) |
773 | + self._cache[dbname]['product.product.%s.%s' % (field, value)] = key |
774 | + break |
775 | + return value |
776 | + |
777 | + else: |
778 | + if fields_def[field.split('.')[0]]['type'] in 'many2one': |
779 | + return _get_obj(field, value, fields_def) |
780 | + |
781 | + raise osv.except_osv(_('Warning !'), _('%s does not exist')%(value,)) |
782 | + |
783 | + i = 1 |
784 | + nb_error = 0 |
785 | + nb_succes = 0 |
786 | + nb_update_success = 0 |
787 | + col_datas = {} |
788 | + nb_imported_lines = 0 |
789 | + header_codes = [x[3] for x in headers] |
790 | + if import_data_obj.pre_hook.get(impobj._name): |
791 | + # for headers mod. |
792 | + col_datas = import_data_obj.pre_hook[impobj._name](impobj, cr, uid, header_codes, {}, col_datas) |
793 | + |
794 | + for row_index, row in enumerate(rows): |
795 | + res, errors, line_data = self.check_error_and_format_row(import_brw.id, row, headers, context=context) |
796 | + if res < 0: |
797 | + save_error(errors, row_index) |
798 | + continue |
799 | + |
800 | + if all(not x for x in line_data): |
801 | + save_warnings( |
802 | + _('Line seemed empty, so this line was ignored') |
803 | + ) |
804 | + continue |
805 | + |
806 | + newo2m = False |
807 | + delimiter = False |
808 | + o2mdatas = {} |
809 | + i += 1 |
810 | + data = {} |
811 | + try: |
812 | + if model == 'hq.entries': |
813 | + hq_entries_obj = self.pool.get('hq.entries.import') |
814 | + hq_entries_obj.update_hq_entries(cr, uid, line_data, context=context) |
815 | + continue |
816 | + |
817 | + n = 0 |
818 | + line_ok = True |
819 | + if import_data_obj.pre_hook.get(impobj._name): |
820 | + import_data_obj.pre_hook[impobj._name](impobj, cr, uid, header_codes, line_data, col_datas) |
821 | + |
822 | + for n, h in enumerate(header_codes): |
823 | + if isinstance(line_data[n], basestring): |
824 | + line_data[n] = line_data[n].rstrip() |
825 | + |
826 | + # UFTP-327 |
827 | + # if required reject cells with exceeded field length |
828 | + if 'import_data_field_max_size' in context: |
829 | + if h in context['import_data_field_max_size']: |
830 | + max_size = context['import_data_field_max_size'][h] |
831 | + if len(line_data[n]) > max_size: |
832 | + msg_tpl = "field '%s' value exceed field length of %d" |
833 | + msg = msg_tpl % (h , max_size, ) |
834 | + logging.getLogger('import data').info( |
835 | + 'Error %s'% (msg, )) |
836 | + cr.rollback() |
837 | + error = "Line %s, row: %s, %s" % (i, n, msg, ) |
838 | + save_error(error, row_index) |
839 | + nb_error += 1 |
840 | + line_ok = False |
841 | + break |
842 | + |
843 | + if newo2m and ('.' not in h or h.split('.')[0] != newo2m or h.split('.')[1] == delimiter): |
844 | + data.setdefault(newo2m, []).append((0, 0, o2mdatas.copy())) |
845 | + o2mdatas = {} |
846 | + delimiter = False |
847 | + newo2m = False |
848 | + if '.' not in h: |
849 | + # type datetime, date, bool, int, float |
850 | + value = process_data(h, line_data[n], fields_def) |
851 | + if value is not None: |
852 | + data[h] = value |
853 | + else: |
854 | + points = h.split('.') |
855 | + if row[n] and fields_def[points[0]]['type'] == 'one2many': |
856 | + newo2m = points[0] |
857 | + delimiter = points[1] |
858 | + new_fields_def = self.pool.get(fields_def[newo2m]['relation']).fields_get(cr, uid, context=context) |
859 | + o2mdatas[points[1]] = process_data('.'.join(points[1:]), line_data[n], new_fields_def) |
860 | + elif fields_def[points[0]]['type'] == 'many2one': |
861 | + if not line_data[n]: |
862 | + data[points[0]] = False |
863 | + elif line_data[n]: |
864 | + data[points[0]] = _get_obj(h, line_data[n], fields_def) or False |
865 | + elif fields_def[points[0]]['type'] == 'many2many' and line_data[n]: |
866 | + data.setdefault(points[0], []).append((4, _get_obj(h, line_data[n], fields_def))) |
867 | + if not line_ok: |
868 | + continue |
869 | + if newo2m and o2mdatas: |
870 | + data.setdefault(newo2m, []).append((0, 0, o2mdatas.copy())) |
871 | + |
872 | + if import_data_obj.post_hook.get(impobj._name): |
873 | + import_data_obj.post_hook[impobj._name](impobj, cr, uid, data, line_data, header_codes) |
874 | + |
875 | + # Search if an object already exist. If not, create it. |
876 | + ids_to_update = [] |
877 | + |
878 | + if impobj._name == 'product.product': |
879 | + # Allow to update the product, use xmlid_code or default_code |
880 | + if 'xmlid_code' in data: |
881 | + ids_to_update = impobj.search(cr, uid, [('xmlid_code', |
882 | + '=', data['xmlid_code'])], order='NO_ORDER') |
883 | + if 'default_code' in data: |
884 | + ids_to_update = impobj.search(cr, uid, [('default_code', |
885 | + '=', data['default_code'])], order='NO_ORDER') |
886 | + elif impobj._name == 'product.nomenclature': |
887 | + ids_to_update = impobj.search(cr, uid, [('msfid', '=', |
888 | + data['msfid'])], order='NO_ORDER') |
889 | + elif impobj._name == 'product.category': |
890 | + ids_to_update = impobj.search(cr, uid, [('msfid', '=', |
891 | + data['msfid'])], order='NO_ORDER') |
892 | + |
893 | + if ids_to_update: |
894 | + #UF-2170: remove the standard price value from the list for update product case |
895 | + if 'standard_price' in data: |
896 | + del data['standard_price'] |
897 | + impobj.write(cr, uid, ids_to_update, data) |
898 | + nb_update_success += 1 |
899 | + |
900 | + else: |
901 | + impobj.create(cr, uid, data, context={'from_import_menu': True}) |
902 | + nb_succes += 1 |
903 | + except osv.except_osv, e: |
904 | + logging.getLogger('import data').info('Error %s' % e.value) |
905 | + cr.rollback() |
906 | + save_error(e.value, row_index) |
907 | + nb_error += 1 |
908 | + except Exception, e: |
909 | + cr.rollback() |
910 | + logging.getLogger('import data').info('Error %s' % e) |
911 | + save_error(e, row_index) |
912 | + nb_error += 1 |
913 | + else: |
914 | + nb_imported_lines += 1 |
915 | + |
916 | + self.write(cr, uid, [import_brw.id], {'total_lines_imported': nb_imported_lines}, context=context) |
917 | + |
918 | + warn_msg = '' |
919 | + for line_number in sorted(import_warnings.keys()): |
920 | + warnings = import_warnings[line_number] |
921 | + for warn in warnings: |
922 | + warn_msg += _('Line %s: %s') % (line, warn) |
923 | + if not warn_msg.endswith('\n'): |
924 | + warn_msg += '\n' |
925 | + |
926 | + err_msg = '' |
927 | + for line_number in sorted(import_errors.keys()): |
928 | + errors = import_errors[line_number] |
929 | + for err in errors: |
930 | + err_msg += _('Line %s: %s') % (line_number, err) |
931 | + if not err_msg.endswith('\n'): |
932 | + err_msg += '\n' |
933 | + |
934 | + if err_msg: |
935 | + cr.rollback() |
936 | + |
937 | + info_msg = _('''Processing of file completed in %s second(s)! |
938 | +- Total lines to import: %s |
939 | +- Total lines %s: %s %s |
940 | +- Total lines with errors: %s %s |
941 | +%s |
942 | + ''') % ( |
943 | + str(round(time.time() - start_time, 1)), |
944 | + import_brw.total_lines_to_import-1, |
945 | + err_msg and _('without errors') or _('imported'), |
946 | + nb_imported_lines, |
947 | + warn_msg and _('(%s line(s) with warning - see warning messages below)') % ( |
948 | + len(import_warnings.keys()) or '', |
949 | + ), |
950 | + err_msg and len(import_errors.keys()) or 0, |
951 | + err_msg and _('(see error messages below)'), |
952 | + err_msg and _("no data will be imported until all the error messages are corrected") or '', |
953 | + ) |
954 | + |
955 | + self.write(cr, uid, [import_brw.id], { |
956 | + 'error_message': err_msg, |
957 | + 'show_error': err_msg and True or False, |
958 | + 'warning_message': warn_msg, |
959 | + 'show_warning': warn_msg and True or False, |
960 | + 'info_message': info_msg, |
961 | + 'state': 'done', |
962 | + 'end_date': time.strftime('%Y-%m-%d %H:%M:%S'), |
963 | + }, context=context) |
964 | + |
965 | + if import_data_obj.post_load_hook.get(impobj._name): |
966 | + import_data_obj.post_load_hook[impobj._name](impobj, cr, uid) |
967 | + |
968 | + if impobj == 'product.product': |
969 | + # Clear the cache |
970 | + self._cache[dbname] = {} |
971 | + prod_nomenclature_obj._cache[dbname] = {} |
972 | + |
973 | + |
974 | + cr.commit() |
975 | + cr.close() |
976 | + |
977 | + return True |
978 | + |
979 | +msf_import_export() |
980 | + |
981 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
982 | |
983 | === added file 'bin/addons/msf_doc_import/msf_import_export_conf.py' |
984 | --- bin/addons/msf_doc_import/msf_import_export_conf.py 1970-01-01 00:00:00 +0000 |
985 | +++ bin/addons/msf_doc_import/msf_import_export_conf.py 2017-09-27 13:17:20 +0000 |
986 | @@ -0,0 +1,579 @@ |
987 | +# encoding: utf-8 |
988 | +############################################################################## |
989 | +# |
990 | +# OpenERP, Open Source Management Solution |
991 | +# Copyright (C) 2017 MSF, TeMPO Consulting |
992 | +# |
993 | +# This program is free software: you can redistribute it and/or modify |
994 | +# it under the terms of the GNU General Public License as published by |
995 | +# the Free Software Foundation, either version 3 of the License, or |
996 | +# (at your option) any later version. |
997 | +# |
998 | +# This program is distributed in the hope that it will be useful, |
999 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1000 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1001 | +# GNU General Public License for more details. |
1002 | +# |
1003 | +# You should have received a copy of the GNU General Public License |
1004 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1005 | +# |
1006 | +############################################################################## |
1007 | + |
1008 | +from tools.translate import _ |
1009 | + |
1010 | +MODEL_DICT = { |
1011 | + # SUPPLY |
1012 | + 'products': { |
1013 | + 'name': 'Products', |
1014 | + 'domain_type': 'supply', |
1015 | + 'model': 'product.product', |
1016 | + }, |
1017 | + 'product_nomenclature': { |
1018 | + 'name': 'Product Nomenclature', |
1019 | + 'domain_type': 'supply', |
1020 | + 'model': 'product.nomenclature', |
1021 | + }, |
1022 | + 'product_category': { |
1023 | + 'name': 'Product Categories', |
1024 | + 'domain_type': 'supply', |
1025 | + 'model': 'product.category', |
1026 | + }, |
1027 | + 'product_list': { |
1028 | + 'name': 'Products Lists', |
1029 | + 'domain_type': 'supply', |
1030 | + 'model': 'product.list', |
1031 | + }, |
1032 | + 'product_list_line': { |
1033 | + 'name': 'Products Lists Lines', |
1034 | + 'domain_type': 'supply', |
1035 | + 'model': 'product.list.line', |
1036 | + }, |
1037 | + 'suppliers': { |
1038 | + 'name': 'Suppliers', |
1039 | + 'domain_type': 'supply', |
1040 | + 'model': 'res.partner', |
1041 | + 'domain': [('supplier', '=', True)], |
1042 | + }, |
1043 | + 'supplier_catalogues': { |
1044 | + 'name': 'Supplier Catalogues', |
1045 | + 'domain_type': 'supply', |
1046 | + 'model': 'supplier.catalogue', |
1047 | + }, |
1048 | + 'supplier_catalogues_lines': { |
1049 | + 'name': 'Supplier Catalogue Lines', |
1050 | + 'domain_type': 'supply', |
1051 | + 'model': 'supplier.catalogue.line', |
1052 | + }, |
1053 | + |
1054 | + |
1055 | + # FINANCE |
1056 | + 'gl_accounts': { |
1057 | + 'name': 'GL Accounts', |
1058 | + 'domain_type': 'finance', |
1059 | + 'model': 'account.account' |
1060 | + }, |
1061 | + 'gl_journals': { |
1062 | + 'name': 'GL Journals', |
1063 | + 'domain_type': 'finance', |
1064 | + 'model': 'account.journal' |
1065 | + }, |
1066 | + 'analytic_accounts': { |
1067 | + 'name': 'Analytic Accounts', |
1068 | + 'domain_type': 'finance', |
1069 | + 'model': 'account.analytic.account' |
1070 | + }, |
1071 | + 'analytic_journals': { |
1072 | + 'name': 'Analytic Journals', |
1073 | + 'domain_type': 'finance', |
1074 | + 'model': 'account.analytic.journal' |
1075 | + }, |
1076 | + 'employees': { |
1077 | + 'name': 'Employees', |
1078 | + 'domain_type': 'finance', |
1079 | + 'model': 'hr.employee' |
1080 | + }, |
1081 | + 'hq_entries': { |
1082 | + 'name': 'HQ Entries', |
1083 | + 'domain_type': 'finance', |
1084 | + 'model': 'hq.entries' |
1085 | + }, |
1086 | + 'currency_rate': { |
1087 | + 'name': 'Currencies Rates', |
1088 | + 'domain_type': 'finance', |
1089 | + 'model': 'res.currency.rate' |
1090 | + }, |
1091 | + 'budget': { |
1092 | + 'name': 'Budget', |
1093 | + 'domain_type': 'finance', |
1094 | + 'model': 'msf.budget' |
1095 | + }, |
1096 | + |
1097 | + |
1098 | + # NON FUNCTIONNAL |
1099 | + 'user_groups': { |
1100 | + 'name': 'User Groups', |
1101 | + 'domain_type': 'non_functionnal', |
1102 | + 'model': 'res.groups' |
1103 | + }, |
1104 | + 'user_access': { |
1105 | + 'name': 'User Access', |
1106 | + 'domain_type': 'non_functionnal', |
1107 | + 'model': 'user.access.configurator' |
1108 | + }, |
1109 | + 'record_rules': { |
1110 | + 'name': 'Record Rules', |
1111 | + 'domain_type': 'non_functionnal', |
1112 | + 'model': 'ir.rule' |
1113 | + }, |
1114 | + 'access_control_list': { |
1115 | + 'name': 'Access Controls List', |
1116 | + 'domain_type': 'non_functionnal', |
1117 | + 'model': 'ir.model.access' |
1118 | + }, |
1119 | + 'field_access_rules': { |
1120 | + 'name': 'Field Access Rules', |
1121 | + 'domain_type': 'non_functionnal', |
1122 | + 'model': 'msf_field_access_rights.field_access_rule' |
1123 | + }, |
1124 | + 'field_access_rule_lines': { |
1125 | + 'name': 'Field Access Rule Lines', |
1126 | + 'domain_type': 'non_functionnal', |
1127 | + 'model': 'msf_field_access_rights.field_access_rule_line' |
1128 | + }, |
1129 | + 'button_access_rules': { |
1130 | + 'name': 'Button Access Rules', |
1131 | + 'domain_type': 'non_functionnal', |
1132 | + 'model': 'msf_button_access_rights.button_access_rule' |
1133 | + }, |
1134 | + 'window_actions': { |
1135 | + 'name': 'Window Actions', |
1136 | + 'domain_type': 'non_functionnal', |
1137 | + 'model': 'ir.actions.act_window' |
1138 | + }, |
1139 | +} |
1140 | + |
1141 | +MODEL_DATA_DICT = { |
1142 | + # SUPPLY |
1143 | + 'products': { |
1144 | + 'header_list': [ |
1145 | + 'default_code', |
1146 | + 'name', |
1147 | + 'xmlid_code', |
1148 | + 'old_code', |
1149 | + 'type', |
1150 | + 'transport_ok', |
1151 | + 'subtype', |
1152 | + 'asset_type_id.name', |
1153 | + 'procure_method', |
1154 | + 'supply_method', |
1155 | + 'standard_price', |
1156 | + 'volume', |
1157 | + 'weight', |
1158 | + 'international_status.name', |
1159 | + 'state.name', |
1160 | + 'active', |
1161 | + 'perishable', |
1162 | + 'batch_management', |
1163 | + 'uom_id.name', |
1164 | + 'uom_po_id.name', |
1165 | + 'nomen_manda_0.name', |
1166 | + 'nomen_manda_1.name', |
1167 | + 'nomen_manda_2.name', |
1168 | + 'nomen_manda_3.name', |
1169 | + 'life_time', |
1170 | + 'use_time', |
1171 | + 'short_shelf_life', |
1172 | + 'alert_time', |
1173 | + 'heat_sensitive_item.code', |
1174 | + 'cold_chain', |
1175 | + 'sterilized', |
1176 | + 'single_use', |
1177 | + 'narcotic', |
1178 | + 'justification_code_id.code', |
1179 | + 'controlled_substance', |
1180 | + 'closed_article', |
1181 | + 'restricted_country', |
1182 | + 'country_restriction', |
1183 | + 'dangerous_goods', |
1184 | + 'un_code', |
1185 | + 'criticism', |
1186 | + 'abc_class', |
1187 | + 'product_catalog_path', |
1188 | + 'description', |
1189 | + 'description2', |
1190 | + 'description_sale', |
1191 | + 'description_purchase', |
1192 | + 'procure_delay', |
1193 | + 'property_account_income.code', |
1194 | + 'property_account_expense.code', |
1195 | + ], |
1196 | + 'required_field_list': [ |
1197 | + 'name', |
1198 | + 'international_status.name', |
1199 | + 'nomen_manda_0.name', |
1200 | + 'nomen_manda_1.name', |
1201 | + 'nomen_manda_2.name', |
1202 | + 'nomen_manda_3.name', |
1203 | + ], |
1204 | + 'hide_download_all_entries': True, |
1205 | + }, |
1206 | + 'product_nomenclature': { |
1207 | + 'header_list': [ |
1208 | + 'level', |
1209 | + 'name', |
1210 | + 'type', |
1211 | + 'parent_id.msfid', |
1212 | + 'msfid', |
1213 | + ], |
1214 | + 'required_field_list': [ |
1215 | + 'level', |
1216 | + 'name', |
1217 | + ], |
1218 | + 'hide_download_3_entries': True, |
1219 | + 'hide_download_all_entries': True, |
1220 | + }, |
1221 | + 'product_category': { |
1222 | + 'header_list': [ |
1223 | + 'type', |
1224 | + 'property_account_expense_categ', |
1225 | + 'property_account_income_categ', |
1226 | + 'name', |
1227 | + 'property_stock_journal', |
1228 | + 'donation_expense_account', |
1229 | + 'family_id', |
1230 | + 'msfid', |
1231 | + ], |
1232 | + 'required_field_list': [ |
1233 | + 'name', |
1234 | + 'family_id', |
1235 | + 'msfid', |
1236 | + ], |
1237 | + }, |
1238 | + 'product_list': { |
1239 | + 'header_list': [ |
1240 | + 'name', |
1241 | + 'type', |
1242 | + 'creator', |
1243 | + 'ref', |
1244 | + ], |
1245 | + 'required_field_list': [ |
1246 | + 'name', |
1247 | + 'type', |
1248 | + 'creator', |
1249 | + ], |
1250 | + }, |
1251 | + 'product_list_line': { |
1252 | + 'header_list': [ |
1253 | + 'list_id.name', |
1254 | + 'ref', |
1255 | + 'name', |
1256 | + 'comment', |
1257 | + ], |
1258 | + 'required_field_list': [ |
1259 | + 'ref', |
1260 | + 'name', |
1261 | + ], |
1262 | + }, |
1263 | + 'suppliers': { |
1264 | + 'header_list': [ |
1265 | + 'address.type', |
1266 | + 'address.city', |
1267 | + 'address.name', |
1268 | + 'address.street', |
1269 | + 'address.zip', |
1270 | + 'address.country_id.name', |
1271 | + 'address.email', |
1272 | + 'property_account_payable.code', |
1273 | + 'property_account_receivable.code', |
1274 | + 'name', |
1275 | + 'lang', |
1276 | + 'partner_type', |
1277 | + 'customer', |
1278 | + 'supplier', |
1279 | + 'property_product_pricelist_purchase.currency_id', |
1280 | + 'property_product_pricelist.currency_id', |
1281 | + ], |
1282 | + 'required_field_list': [ |
1283 | + 'property_account_payable.code', |
1284 | + 'property_account_receivable.code', |
1285 | + 'name', |
1286 | + ], |
1287 | + }, |
1288 | + 'supplier_catalogues': { |
1289 | + 'header_list': [ |
1290 | + 'name', |
1291 | + 'period_from', |
1292 | + 'period_to', |
1293 | + 'currency_id.name', |
1294 | + 'partner_id.name', |
1295 | + ], |
1296 | + 'required_field_list': [ |
1297 | + 'name', |
1298 | + 'currency_id.name', |
1299 | + 'partner_id.name', |
1300 | + ], |
1301 | + }, |
1302 | + 'supplier_catalogues_lines': { |
1303 | + 'header_list': [ |
1304 | + 'catalogue_id.name', |
1305 | + 'product_id.code', |
1306 | + 'product_id.name', |
1307 | + 'line_uom_id.name', |
1308 | + 'min_qty', |
1309 | + 'unit_price', |
1310 | + 'rounding', |
1311 | + 'min_order_qty', |
1312 | + 'comment', |
1313 | + ], |
1314 | + 'required_field_list': [ |
1315 | + 'catalogue_id.name', |
1316 | + 'product_id.code', |
1317 | + 'line_uom_id.name', |
1318 | + 'min_qty', |
1319 | + 'unit_price', |
1320 | + ], |
1321 | + }, |
1322 | + |
1323 | + |
1324 | + # FINANCE |
1325 | + 'gl_accounts': { |
1326 | + 'header_list': [ |
1327 | + 'user_type.name', |
1328 | + 'accrual_account', |
1329 | + 'activation_date', |
1330 | + 'code', |
1331 | + 'default_destination_id.id', |
1332 | + 'inactivation_date', |
1333 | + 'type', |
1334 | + 'name', |
1335 | + 'note', |
1336 | + 'type_for_register', |
1337 | + 'reconcile', |
1338 | + 'parent_id.code', |
1339 | + 'is_not_hq_correctible', |
1340 | + 'shrink_entries_for_hq', |
1341 | + 'currency_revaluation', |
1342 | + ], |
1343 | + 'required_field_list': [ |
1344 | + 'user_type.name', |
1345 | + 'activation_date', |
1346 | + 'code', |
1347 | + 'type', |
1348 | + 'name', |
1349 | + 'type_for_register', |
1350 | + ], |
1351 | + }, |
1352 | + 'gl_journals': { |
1353 | + 'header_list': [ |
1354 | + 'code', |
1355 | + 'currency.name', |
1356 | + 'default_credit_account_id.code', |
1357 | + 'default_debit_account_id.code', |
1358 | + 'name', |
1359 | + 'type', |
1360 | + 'analytic_journal_id.name', |
1361 | + ], |
1362 | + 'required_field_list': [ |
1363 | + 'code', |
1364 | + 'name', |
1365 | + 'type', |
1366 | + 'analytic_journal_id.name', |
1367 | + ], |
1368 | + }, |
1369 | + 'analytic_accounts': { |
1370 | + 'header_list': [ |
1371 | + 'name', |
1372 | + 'code', |
1373 | + 'category', |
1374 | + 'parent_id.code', |
1375 | + 'type', |
1376 | + 'date_start', |
1377 | + ], |
1378 | + 'required_field_list': [ |
1379 | + 'name', |
1380 | + 'code', |
1381 | + 'category', |
1382 | + 'parent_id.code', |
1383 | + 'date_start', |
1384 | + ], |
1385 | + }, |
1386 | + 'analytic_journals': { |
1387 | + 'header_list': [ |
1388 | + 'active', |
1389 | + 'code', |
1390 | + 'name', |
1391 | + 'type', |
1392 | + ], |
1393 | + 'required_field_list': [ |
1394 | + 'code', |
1395 | + 'name', |
1396 | + 'type', |
1397 | + ], |
1398 | + }, |
1399 | + 'employees': { |
1400 | + 'header_list': [ |
1401 | + 'name', |
1402 | + 'identification_id', |
1403 | + 'active', |
1404 | + ], |
1405 | + 'required_field_list': [ |
1406 | + 'name', |
1407 | + 'identification_id', |
1408 | + ], |
1409 | + 'hide_export': True, |
1410 | + }, |
1411 | + 'hq_entries': { |
1412 | + 'header_list': [ |
1413 | + 'name', |
1414 | + 'ref', |
1415 | + 'document_date', |
1416 | + 'date', |
1417 | + 'account_id', |
1418 | + 'partner_txt', |
1419 | + 'amount', |
1420 | + 'currency_id.name', |
1421 | + 'destination_id', |
1422 | + 'cost_center_id', |
1423 | + 'analytic_id', |
1424 | + 'free_1_id', |
1425 | + 'free_2_id', |
1426 | + ], |
1427 | + 'required_field_list': [ |
1428 | + 'name', |
1429 | + 'account_id', |
1430 | + 'currency_id.name', |
1431 | + 'destination_id', |
1432 | + 'analytic_id', |
1433 | + ], |
1434 | + 'csv_button': True, |
1435 | + 'hide_export': True, |
1436 | + }, |
1437 | + 'currency_rate': { |
1438 | + 'header_list': [ |
1439 | + 'name', |
1440 | + 'currency_id.name', |
1441 | + 'rate', |
1442 | + ], |
1443 | + 'required_field_list': [ |
1444 | + 'name', |
1445 | + 'rate', |
1446 | + 'currency_id.name', |
1447 | + ], |
1448 | + }, |
1449 | + 'budget': { |
1450 | + 'header_list': [], |
1451 | + 'required_field_list': [], |
1452 | + 'csv_button': True, |
1453 | + 'hide_export': True, |
1454 | + }, |
1455 | + |
1456 | + |
1457 | + # NON FUNCTIONNAL |
1458 | + 'user_groups': { |
1459 | + 'header_list': [ |
1460 | + 'name', |
1461 | + ], |
1462 | + 'required_field_list': [ |
1463 | + 'name', |
1464 | + ], |
1465 | + }, |
1466 | + 'user_access': { |
1467 | + 'header_list': [ |
1468 | + ], |
1469 | + 'required_field_list': [ |
1470 | + ], |
1471 | + 'hide_export': True, |
1472 | + }, |
1473 | + 'record_rules': { |
1474 | + 'header_list': [ |
1475 | + 'model_id.model', |
1476 | + 'name', |
1477 | + 'global', |
1478 | + 'domain_force', |
1479 | + 'perm_read', |
1480 | + 'perm_write', |
1481 | + 'perm_create', |
1482 | + 'perm_unlink', |
1483 | + ], |
1484 | + 'required_field_list': [ |
1485 | + 'model_id.model', |
1486 | + 'name', |
1487 | + ], |
1488 | + }, |
1489 | + 'access_control_list': { |
1490 | + 'header_list': [ |
1491 | + 'name', |
1492 | + 'model_id.model', |
1493 | + 'group_id.name', |
1494 | + 'perm_read', |
1495 | + 'perm_write', |
1496 | + 'perm_create', |
1497 | + 'perm_unlink', |
1498 | + ], |
1499 | + 'required_field_list': [ |
1500 | + 'name', |
1501 | + 'model_id.model', |
1502 | + ], |
1503 | + }, |
1504 | + 'field_access_rules': { |
1505 | + 'header_list': [ |
1506 | + 'name', |
1507 | + 'model_id.model', |
1508 | + 'instance_level', |
1509 | + 'domain_text', |
1510 | + 'status', |
1511 | + ], |
1512 | + 'required_field_list': [ |
1513 | + 'name', |
1514 | + 'model_id.model', |
1515 | + 'instance_level', |
1516 | + ], |
1517 | + }, |
1518 | + 'field_access_rule_lines': { |
1519 | + 'header_list': [ |
1520 | + 'field_access_rule.name', |
1521 | + 'field_access_rule_model_id', |
1522 | + 'field.name', |
1523 | + 'field_name', |
1524 | + 'write_access', |
1525 | + 'value_not_synchronized_on_create', |
1526 | + 'value_not_synchronized_on_write', |
1527 | + ], |
1528 | + 'required_field_list': [ |
1529 | + 'field_access_rule', |
1530 | + 'field', |
1531 | + ], |
1532 | + }, |
1533 | + 'button_access_rules': { |
1534 | + 'header_list': [ |
1535 | + 'model_id.model', |
1536 | + 'view_id.name', |
1537 | + 'label', |
1538 | + 'name', |
1539 | + 'group_names', |
1540 | + 'type', |
1541 | + ], |
1542 | + 'required_field_list': [ |
1543 | + 'model_id.model', |
1544 | + 'view_id.name', |
1545 | + 'name', |
1546 | + ], |
1547 | + }, |
1548 | + 'window_actions': { |
1549 | + 'header_list': [ |
1550 | + 'name', |
1551 | + 'res_model', |
1552 | + 'view_type', |
1553 | + 'view_id.name', |
1554 | + 'domain', |
1555 | + 'groups_id', |
1556 | + ], |
1557 | + 'required_field_list': [ |
1558 | + 'name', |
1559 | + 'res_model', |
1560 | + 'view_type', |
1561 | + ], |
1562 | + }, |
1563 | +} |
1564 | + |
1565 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1566 | |
1567 | === added file 'bin/addons/msf_doc_import/report/export_generic.mako' |
1568 | --- bin/addons/msf_doc_import/report/export_generic.mako 1970-01-01 00:00:00 +0000 |
1569 | +++ bin/addons/msf_doc_import/report/export_generic.mako 2017-09-27 13:17:20 +0000 |
1570 | @@ -0,0 +1,137 @@ |
1571 | +<?xml version="1.0"?> |
1572 | +<?mso-application progid="Excel.Sheet"?> |
1573 | +<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" |
1574 | + xmlns:o="urn:schemas-microsoft-com:office:office" |
1575 | + xmlns:x="urn:schemas-microsoft-com:office:excel" |
1576 | + xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" |
1577 | + xmlns:html="http://www.w3.org/TR/REC-html40"> |
1578 | + |
1579 | + <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> |
1580 | + <Author>MSFUser</Author> |
1581 | + <LastAuthor>MSFUser</LastAuthor> |
1582 | + <Created>2012-06-18T15:46:09Z</Created> |
1583 | + <Company>Medecins Sans Frontieres</Company> |
1584 | + <Version>11.9999</Version> |
1585 | + </DocumentProperties> |
1586 | + |
1587 | + <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> |
1588 | + <WindowHeight>13170</WindowHeight> |
1589 | + <WindowWidth>19020</WindowWidth> |
1590 | + <WindowTopX>120</WindowTopX> |
1591 | + <WindowTopY>60</WindowTopY> |
1592 | + <ProtectStructure>False</ProtectStructure> |
1593 | + <ProtectWindows>False</ProtectWindows> |
1594 | + </ExcelWorkbook> |
1595 | + |
1596 | + <Styles> |
1597 | + <Style ss:ID="header"> |
1598 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1599 | + <Interior ss:Color="#ffcc99" ss:Pattern="Solid"/> |
1600 | + <Font ss:Bold="1" ss:Color="#000000" /> |
1601 | + <Borders> |
1602 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1603 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1604 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1605 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1606 | + </Borders> |
1607 | + <Protection /> |
1608 | + </Style> |
1609 | + <Style ss:ID="String"> |
1610 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1611 | + <Borders> |
1612 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1613 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1614 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1615 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1616 | + </Borders> |
1617 | + <Protection ss:Protected="0" /> |
1618 | + </Style> |
1619 | + <Style ss:ID="Boolean"> |
1620 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1621 | + <Borders> |
1622 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1623 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1624 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1625 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1626 | + </Borders> |
1627 | + <Protection ss:Protected="0" /> |
1628 | + </Style> |
1629 | + <Style ss:ID="Float"> |
1630 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1631 | + <Borders> |
1632 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1633 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1634 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1635 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1636 | + </Borders> |
1637 | + <NumberFormat ss:Format="Fixed" /> |
1638 | + <Protection ss:Protected="0" /> |
1639 | + </Style> |
1640 | + <Style ss:ID="Number"> |
1641 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1642 | + <Borders> |
1643 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1644 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1645 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1646 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1647 | + </Borders> |
1648 | + <NumberFormat ss:Format="Fixed" /> |
1649 | + <Protection ss:Protected="0" /> |
1650 | + </Style> |
1651 | + <Style ss:ID="DateTime"> |
1652 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1653 | + <Borders> |
1654 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/> |
1655 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/> |
1656 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/> |
1657 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/> |
1658 | + </Borders> |
1659 | + <NumberFormat ss:Format="Short Date" /> |
1660 | + <Protection ss:Protected="0" /> |
1661 | + </Style> |
1662 | + </Styles> |
1663 | + |
1664 | + <ss:Worksheet ss:Name="${data.get('model_name', _('Sheet 1'))|x}" ss:Protected="0"> |
1665 | + |
1666 | + <Table x:FullColumns="1" x:FullRows="1"> |
1667 | + |
1668 | + <% rows = getRows(data['model'], data['fields'], data.get('nb_lines'), data.get('domain'), data.get('template_only', False), data['context']) %> |
1669 | + <% headers = getHeaders(data['model'], data['fields'], rows, data['context']) %> |
1670 | + % for col in headers: |
1671 | + <Column ss:AutoFitWidth="1" ss:Width="${col[2] or 70|x}" ss:StyleID="${col[1]|x}" /> |
1672 | + % endfor |
1673 | + |
1674 | + <Row> |
1675 | + % for col in headers: |
1676 | + <Cell ss:StyleID="header"> |
1677 | + <Data ss:Type="String">${col[0]|x}</Data> |
1678 | + </Cell> |
1679 | + % endfor |
1680 | + </Row> |
1681 | + |
1682 | + % if not data.get('template_only', False): |
1683 | + % for row in rows: |
1684 | + <Row> |
1685 | + % for index, cell in enumerate(row): |
1686 | + <Cell ss:StyleID="${headers[index][1]|x}"> |
1687 | + % if headers[index][1] == 'String' and not cell: |
1688 | + <Data ss:Type="String"></Data> |
1689 | + % else: |
1690 | + <Data ss:Type="String">${cell|x}</Data> |
1691 | + % endif |
1692 | + </Cell> |
1693 | + % endfor |
1694 | + </Row> |
1695 | + % endfor |
1696 | + % endif |
1697 | + </Table> |
1698 | + |
1699 | + <x:WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> |
1700 | + <ProtectScenarios>False</ProtectScenarios> |
1701 | + <EnableSelection>UnlockedCells</EnableSelection> |
1702 | + <AllowInsertRows /> |
1703 | + </x:WorksheetOptions> |
1704 | + |
1705 | + </ss:Worksheet> |
1706 | + |
1707 | +</Workbook> |
1708 | |
1709 | === modified file 'bin/addons/msf_doc_import/report/import_generic_template.mako' |
1710 | --- bin/addons/msf_doc_import/report/import_generic_template.mako 2016-08-15 11:49:05 +0000 |
1711 | +++ bin/addons/msf_doc_import/report/import_generic_template.mako 2017-09-27 13:17:20 +0000 |
1712 | @@ -46,6 +46,27 @@ |
1713 | </Borders> |
1714 | <Protection ss:Protected="0" /> |
1715 | </Style> |
1716 | + <Style ss:ID="Boolean"> |
1717 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1718 | + <Borders> |
1719 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1720 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1721 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1722 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1723 | + </Borders> |
1724 | + <Protection ss:Protected="0" /> |
1725 | + </Style> |
1726 | + <Style ss:ID="Float"> |
1727 | + <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1728 | + <Borders> |
1729 | + <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" /> |
1730 | + <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" /> |
1731 | + <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" /> |
1732 | + <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" /> |
1733 | + </Borders> |
1734 | + <NumberFormat ss:Format="Fixed" /> |
1735 | + <Protection ss:Protected="0" /> |
1736 | + </Style> |
1737 | <Style ss:ID="Number"> |
1738 | <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> |
1739 | <Borders> |
1740 | |
1741 | === modified file 'bin/addons/msf_doc_import/report/import_generic_template.py' |
1742 | --- bin/addons/msf_doc_import/report/import_generic_template.py 2016-07-27 09:38:38 +0000 |
1743 | +++ bin/addons/msf_doc_import/report/import_generic_template.py 2017-09-27 13:17:20 +0000 |
1744 | @@ -19,12 +19,64 @@ |
1745 | # |
1746 | ############################################################################## |
1747 | |
1748 | +from report import report_sxw |
1749 | from report_webkit.webkit_report import XlsWebKitParser |
1750 | |
1751 | + |
1752 | XlsWebKitParser( |
1753 | 'report.wizard.import.generic.template', |
1754 | 'abstract.wizard.import', |
1755 | 'addons/msf_doc_import/report/import_generic_template.mako', |
1756 | ) |
1757 | |
1758 | + |
1759 | +class report_generic_export_parser(report_sxw.rml_parse): |
1760 | + |
1761 | + def __init__(self, cr, uid, name, context=None): |
1762 | + super(report_generic_export_parser, self).__init__(cr, uid, name, context=context) |
1763 | + self.localcontext.update({ |
1764 | + 'getHeaders': self.getHeaders, |
1765 | + 'getRows': self.getRows, |
1766 | + }) |
1767 | + return |
1768 | + |
1769 | + def getHeaders(self, model, field_list, rows, context=None): |
1770 | + ''' |
1771 | + get the column names of the table. Set the type of the column and the |
1772 | + size of it. |
1773 | + ''' |
1774 | + import_export_obj = self.pool.get('msf.import.export') |
1775 | + return import_export_obj._get_headers(self.cr, self.uid, model, |
1776 | + selection=None, field_list=field_list, rows=rows, context=context) |
1777 | + |
1778 | + def getRows(self, model, fields, nb_lines=None, domain=None, |
1779 | + template_only=False, context=None): |
1780 | + """ |
1781 | + Return list of lines from given generic export |
1782 | + """ |
1783 | + if context is None: |
1784 | + context={} |
1785 | + if template_only: |
1786 | + return [] |
1787 | + if not domain: |
1788 | + domain = [] |
1789 | + rows = [] |
1790 | + counter = 0 |
1791 | + chunk_size = 100 |
1792 | + model_obj = self.pool.get(model) |
1793 | + ids = model_obj.search(self.cr, self.uid, domain, limit=nb_lines) |
1794 | + fields = [x.replace('.', '/') for x in fields] |
1795 | + for i in range(0, len(ids), chunk_size): |
1796 | + ids_chunk = ids[i:i + chunk_size] |
1797 | + counter += len(ids_chunk) |
1798 | + context['translate_selection_field'] = True |
1799 | + rows.extend(model_obj.export_data(self.cr, self.uid, ids_chunk, fields, context=context)['datas']) |
1800 | + return rows |
1801 | + |
1802 | +XlsWebKitParser( |
1803 | + 'report.wizard.export.generic', |
1804 | + 'msf.import.export', |
1805 | + 'addons/msf_doc_import/report/export_generic.mako', |
1806 | + parser=report_generic_export_parser, |
1807 | +) |
1808 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1809 | |
1810 | === added file 'bin/addons/msf_doc_import/view/msf_import_export_view.xml' |
1811 | --- bin/addons/msf_doc_import/view/msf_import_export_view.xml 1970-01-01 00:00:00 +0000 |
1812 | +++ bin/addons/msf_doc_import/view/msf_import_export_view.xml 2017-09-27 13:17:20 +0000 |
1813 | @@ -0,0 +1,99 @@ |
1814 | +<?xml version="1.0" encoding="utf-8" ?> |
1815 | +<openerp> |
1816 | +<data> |
1817 | + |
1818 | + <record id="msf_import_export_view" model="ir.ui.view"> |
1819 | + <field name="name">msf.import.export.view</field> |
1820 | + <field name="model">msf.import.export</field> |
1821 | + <field name="type">form</field> |
1822 | + <field name="arch" type="xml"> |
1823 | + <form string="Import / Export"> |
1824 | + <group> |
1825 | + <field name="display_file_import" invisible="1" /> |
1826 | + <field name="display_file_export" invisible="1" /> |
1827 | + <field name="csv_button" invisible="1" /> |
1828 | + <field name="state" invisible="1" /> |
1829 | + <field name='model_list_selection' on_change="domain_type_change(model_list_selection)" /> |
1830 | + </group> |
1831 | + <group col="4" colspan="4"> |
1832 | + <field name="hide_download_3_entries" invisible="1" /> |
1833 | + <field name="hide_download_all_entries" invisible="1" /> |
1834 | + <group colspan="2" col="2" name="file_import" attrs="{'invisible':[('display_file_import', '=', False)]}"> |
1835 | + <separator string="File Import" colspan="2"/> |
1836 | + <field name="display_import_buttons" invisible="1" /> |
1837 | + <field name="import_file" colspan="4" on_change="file_change(import_file)"/> |
1838 | + <button name="test_import" string="Test file" type="object" icon="gtk-ok" colspan="4" attrs="{'invisible':[('display_import_buttons', '=', False)]}" /> |
1839 | + <button name="import_xml" string="Run import" type="object" icon="gtk-execute" colspan="4" attrs="{'invisible': ['|', '|', ('display_import_buttons', '=', False), ('state', '!=', 'draft'), ('csv_button', '=', True)]}" /> |
1840 | + <button name="import_csv" string="Run import" type="object" icon="gtk-execute" colspan="4" attrs="{'invisible': ['|', '|', ('display_import_buttons', '=', False), ('state', '!=', 'draft'), ('csv_button', '=', False)]}" /> |
1841 | + <separator colspan="4" string="Information" /> |
1842 | + <field name="info_message" colspan="4" nolabel="1" /> |
1843 | + </group> |
1844 | + <group colspan="2" col="2" name="file_export"> |
1845 | + <separator string="File Export" colspan="2"/> |
1846 | + <group attrs="{'invisible':[('display_file_export', '=', False)]}"> |
1847 | + <button name="download_template_file" string="Export empty template" icon="gtk-save" help="Download template file" type="object" /> |
1848 | + <button name="download_3_entries_file" string="Export first 3 entries" type="object" icon="gtk-save" colspan="4" attrs="{'invisible':[('hide_download_3_entries', '=', True)]}"/> |
1849 | + <button name="download_all_entries_file" string="Export all data" type="object" icon="gtk-save" colspan="4" attrs="{'invisible':[('hide_download_all_entries', '=', True)]}"/> |
1850 | + </group> |
1851 | + </group> |
1852 | + <group colspan="4" attrs="{'invisible': [('show_warning', '=', False)]}"> |
1853 | + <separator colspan="4" string="Warning messages" /> |
1854 | + <field name="warning_message" nolabel="1" colspan="4" widget="full_text"/> |
1855 | + </group> |
1856 | + |
1857 | + <group colspan="4" attrs="{'invisible': [('show_error', '=', False)]}"> |
1858 | + <separator colspan="4" string="Error messages" /> |
1859 | + <field name="error_message" nolabel="1" colspan="4" widget="full_text"/> |
1860 | + </group> |
1861 | + </group> |
1862 | + </form> |
1863 | + </field> |
1864 | + </record> |
1865 | + |
1866 | + |
1867 | + <record id="msf_import_export_supply_action" model="ir.actions.act_window"> |
1868 | + <field name="name">Supply</field> |
1869 | + <field name="res_model">msf.import.export</field> |
1870 | + <field name="view_type">form</field> |
1871 | + <field name="view_mode">form</field> |
1872 | + <field name="target">current</field> |
1873 | + <field name="context">{'domain_type': 'supply'}</field> |
1874 | + </record> |
1875 | + |
1876 | + <record id="msf_import_export_finance_action" model="ir.actions.act_window"> |
1877 | + <field name="name">Finance</field> |
1878 | + <field name="res_model">msf.import.export</field> |
1879 | + <field name="view_type">form</field> |
1880 | + <field name="view_mode">form</field> |
1881 | + <field name="target">current</field> |
1882 | + <field name="context">{'domain_type': 'finance'}</field> |
1883 | + </record> |
1884 | + |
1885 | + <record id="msf_import_export_non_functional_action" model="ir.actions.act_window"> |
1886 | + <field name="name">Non Functional</field> |
1887 | + <field name="res_model">msf.import.export</field> |
1888 | + <field name="view_type">form</field> |
1889 | + <field name="view_mode">form</field> |
1890 | + <field name="target">current</field> |
1891 | + <field name="context">{'domain_type': 'non_functionnal'}</field> |
1892 | + </record> |
1893 | + |
1894 | + <menuitem id="msf_import_export_menu" |
1895 | + name="Import / Export" |
1896 | + parent="object_query.menu_preferences" /> |
1897 | + |
1898 | + <menuitem id="msf_import_export_supply_menu" |
1899 | + parent="msf_import_export_menu" |
1900 | + action="msf_import_export_supply_action" /> |
1901 | + |
1902 | + <menuitem id="msf_import_export_finance_menu" |
1903 | + parent="msf_import_export_menu" |
1904 | + action="msf_import_export_finance_action" /> |
1905 | + |
1906 | + <menuitem id="msf_import_export_non_functional_menu" |
1907 | + parent="msf_import_export_menu" |
1908 | + action="msf_import_export_non_functional_action" /> |
1909 | + |
1910 | + |
1911 | +</data> |
1912 | +</openerp> |
1913 | |
1914 | === modified file 'bin/addons/msf_doc_import/wizard/abstract_wizard_import.py' |
1915 | --- bin/addons/msf_doc_import/wizard/abstract_wizard_import.py 2017-03-20 09:49:38 +0000 |
1916 | +++ bin/addons/msf_doc_import/wizard/abstract_wizard_import.py 2017-09-27 13:17:20 +0000 |
1917 | @@ -39,7 +39,7 @@ |
1918 | """ |
1919 | Class used to export Header template. |
1920 | """ |
1921 | - type_ok = ['String', 'Number', 'DateTime'] |
1922 | + type_ok = ['String', 'Number', 'DateTime', 'Boolean', 'Float'] |
1923 | |
1924 | def __new__(cls, name, ftype='String', size=70, tech_name=None, required=False): |
1925 | """ |
1926 | @@ -71,12 +71,12 @@ |
1927 | :return: A datetime instance or False |
1928 | """ |
1929 | # US:2527: accept only one format, reject other |
1930 | - date_format = [ |
1931 | + accepted_date_format = [ |
1932 | '%d/%m/%Y', |
1933 | ] |
1934 | |
1935 | d = False |
1936 | - for dformat in date_format: |
1937 | + for dformat in accepted_date_format: |
1938 | try: |
1939 | d = DateTime.strptime(date_value, dformat) |
1940 | d = d.strftime('%Y-%m-%d %H:%M:%S') |
1941 | @@ -130,9 +130,24 @@ |
1942 | return (0, value, None) |
1943 | else: |
1944 | try: |
1945 | + if isinstance(value, basestring): |
1946 | + value = value.rstrip().replace(',', '.') |
1947 | return (0, float(value), None) |
1948 | except Exception as e: |
1949 | return (-1, value, e) |
1950 | + elif header[1] == 'Boolean': |
1951 | + if isinstance(value, bool): |
1952 | + pass |
1953 | + elif value.upper() in ('T', 'TRUE', '1'): |
1954 | + value = True |
1955 | + else: |
1956 | + value = False |
1957 | + elif header[1] == 'Number': |
1958 | + if vtype =='int': |
1959 | + try: |
1960 | + return (0, int(value), None) |
1961 | + except Exception as e: |
1962 | + return (-1, value, e) |
1963 | |
1964 | return (0, value, None) |
1965 | |
1966 | @@ -429,9 +444,19 @@ |
1967 | len(line_content), len(headers) |
1968 | )) |
1969 | |
1970 | + # if the last comlumn(s) is(are) empty, line_content do not contain |
1971 | + # this column: len(line_content) is equal to len(headers) - number of |
1972 | + # empty columns at the end |
1973 | + if len(line_content) < len(headers): |
1974 | + # add None instead of the missing column |
1975 | + line_content += [None for x in range((len(headers) - len(line_content)))] |
1976 | + |
1977 | data = [] |
1978 | errors = [] |
1979 | for col_index, col_value in enumerate(line_content): |
1980 | + if col_value is None: |
1981 | + data.append(None) |
1982 | + continue |
1983 | # Check data values according to expected type |
1984 | chk_res = ImportHeader.check_value(headers[col_index], col_value.data, col_value.type, context=context) |
1985 | data.append(chk_res[1]) |
1986 | |
1987 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
1988 | --- bin/addons/msf_profile/i18n/fr_MF.po 2017-09-08 15:57:28 +0000 |
1989 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2017-09-27 13:17:20 +0000 |
1990 | @@ -4544,13 +4544,14 @@ |
1991 | msgid "Contact Titles" |
1992 | msgstr "Titre/Position Contact" |
1993 | |
1994 | -#. module: msf_button_access_rights |
1995 | +#. modules: msf_button_access_rights, msf_doc_import |
1996 | #: model:ir.actions.act_window,name:msf_button_access_rights.button_access_rule_list |
1997 | #: model:ir.ui.menu,name:msf_button_access_rights.msf_button_access_rules |
1998 | #: view:ir.ui.view:0 |
1999 | #: field:ir.ui.view,button_access_rules_ref:0 |
2000 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:124 |
2001 | msgid "Button Access Rules" |
2002 | -msgstr "Button Access Rules" |
2003 | +msgstr "Règles d'Accès de bouton" |
2004 | |
2005 | #. module: stock |
2006 | #: code:addons/stock/stock.py:1091 |
2007 | @@ -7005,11 +7006,6 @@ |
2008 | msgid "MSF Codification" |
2009 | msgstr "Codification MSF" |
2010 | |
2011 | -#. module: product_list |
2012 | -#: view:product.list.line:0 |
2013 | -msgid "Products" |
2014 | -msgstr "Products" |
2015 | - |
2016 | #. module: base_setup |
2017 | #: view:base.setup.company:0 |
2018 | msgid "Your company information will be used to personalize documents issued with OpenERP such as invoices, sales orders and much more." |
2019 | @@ -13296,12 +13292,6 @@ |
2020 | msgid "Destinations" |
2021 | msgstr "Destinations" |
2022 | |
2023 | -#. module: import_data |
2024 | -#: selection:import_category,object:0 |
2025 | -#: selection:import_nomenclature,object:0 |
2026 | -msgid "Product Nomenclature" |
2027 | -msgstr "Product Nomenclature" |
2028 | - |
2029 | #. module: analytic_distribution |
2030 | #: code:addons/analytic_distribution/account_commitment.py:166 |
2031 | #, python-format |
2032 | @@ -15965,6 +15955,47 @@ |
2033 | msgid "New Zealand" |
2034 | msgstr "Nouvelle-Zélande" |
2035 | |
2036 | +#. modules: msf_doc_import, msf_supply_doc_export |
2037 | +#: code:addons/msf_doc_import/wizard/__init__.py:68 |
2038 | +#: code:addons/msf_doc_import/wizard/__init__.py:73 |
2039 | +#: code:addons/msf_doc_import/wizard/__init__.py:78 |
2040 | +#: code:addons/msf_doc_import/wizard/wizard_in_simulation_screen.py:65 |
2041 | +#: report:addons/msf_supply_doc_export/report/report_real_composition_kit_xls.mako:71 |
2042 | +#, python-format |
2043 | +msgid "Expiry Date" |
2044 | +msgstr "Date d'expiration" |
2045 | + |
2046 | +#. modules: account, msf_outgoing, register_accounting, account_override, purchase_compare_rfq, msf_doc_import, return_claim, analytic_distribution |
2047 | +#: code:addons/account/report/account_general_ledger.py:550 |
2048 | +#: view:account.chart:0 |
2049 | +#: field:account.chart,currency_id:0 |
2050 | +#: view:account.analytic.chart:0 |
2051 | +#: field:account.analytic.chart,currency_id:0 |
2052 | +#: code:addons/msf_doc_import/wizard/wizard_in_simulation_screen.py:63 |
2053 | +#: code:addons/msf_doc_import/wizard/wizard_po_simulation_screen.py:70 |
2054 | +#: field:wizard.import.po.simulation.screen,in_currency:0 |
2055 | +#: field:wizard.import.po.simulation.screen.line,imp_currency:0 |
2056 | +#: field:wizard.import.po.simulation.screen.line,in_currency:0 |
2057 | +#: field:wizard.simu.import.po.line,currency_id:0 |
2058 | +#: field:wizard.simu.import.po.line,initial_currency:0 |
2059 | +#: field:create.picking.move.processor,currency:0 |
2060 | +#: field:internal.move.processor,currency:0 |
2061 | +#: field:outgoing.delivery.move.processor,currency:0 |
2062 | +#: field:ppl.move.processor,currency:0 |
2063 | +#: field:return.ppl.move.processor,currency:0 |
2064 | +#: field:stock.move.in.processor,currency:0 |
2065 | +#: field:stock.move.processor,currency:0 |
2066 | +#: field:validate.move.processor,currency:0 |
2067 | +#: field:wizard.compare.rfq,currency_id:0 |
2068 | +#: field:account.direct.invoice.wizard,currency_id:0 |
2069 | +#: field:wizard.account.invoice,fake_currency_id:0 |
2070 | +#: field:wizard.account.invoice,virtual_currency_id:0 |
2071 | +#: field:claim.product.line,price_currency_claim_product_line:0 |
2072 | +#: field:claim.product.line,price_unit_claim_product_line:0 |
2073 | +#, python-format |
2074 | +msgid "Currency" |
2075 | +msgstr "Devise" |
2076 | + |
2077 | #. module: sale |
2078 | #: help:sale.order.line,delay:0 |
2079 | msgid "Number of days between the order confirmation the shipping of the products to the customer" |
2080 | @@ -17377,6 +17408,7 @@ |
2081 | |
2082 | #. module: msf_doc_import |
2083 | #: view:wizard.import.batch:0 |
2084 | +#: view:msf.import.export:0 |
2085 | msgid "Warning messages" |
2086 | msgstr "Messages d'avertissement" |
2087 | |
2088 | @@ -20661,9 +20693,11 @@ |
2089 | msgid "IN update OUT" |
2090 | msgstr "IN update OUT" |
2091 | |
2092 | -#. module: import_data |
2093 | +#. modules: import_data, msf_doc_import |
2094 | #: code:addons/import_data/import_data.py:317 |
2095 | #: code:addons/import_data/import_data.py:356 |
2096 | +#: code:addons/msf_doc_import/msf_import_export.py:499 |
2097 | +#: code:addons/msf_doc_import/msf_import_export.py:528 |
2098 | #, python-format |
2099 | msgid "%s does not exist" |
2100 | msgstr "%s n'existe pas" |
2101 | @@ -24759,11 +24793,12 @@ |
2102 | msgid "This wizard will validate all journal entries of a particular journal and period. Once journal entries are validated, you can not update them anymore." |
2103 | msgstr "Cet assistant validera toutes les écritures comptables pour un journal particulier et une période. Une fois validées, les écritures comptables ne peuvent plus être modifiées." |
2104 | |
2105 | -#. module: msf_field_access_rights |
2106 | +#. modules: msf_field_access_rights, msf_doc_import |
2107 | #: model:ir.actions.act_window,name:msf_field_access_rights.field_access_rules_list |
2108 | #: model:ir.ui.menu,name:msf_field_access_rights.msf_field_access_rules |
2109 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:114 |
2110 | msgid "Field Access Rules" |
2111 | -msgstr "Field Access Rules" |
2112 | +msgstr "Règles d'Accès au Champs" |
2113 | |
2114 | #. modules: account, msf_outgoing, finance, sync_client, register_accounting, account_override, sourcing, sync_so, res_currency_functional, analytic_distribution |
2115 | #: code:addons/account/report/account_general_ledger.py:252 |
2116 | @@ -25725,9 +25760,10 @@ |
2117 | msgid "No Period found on Invoice!" |
2118 | msgstr "Pas de Période indiquée sur la Facture!" |
2119 | |
2120 | -#. module: supplier_catalogue |
2121 | +#. modules: supplier_catalogue, msf_doc_import |
2122 | #: model:ir.actions.act_window,name:supplier_catalogue.action_supplier_catalogue_line_list |
2123 | #: view:supplier.catalogue.line:0 |
2124 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:53 |
2125 | msgid "Supplier catalogue lines" |
2126 | msgstr "Lignes Catalogue Fournisseur" |
2127 | |
2128 | @@ -25857,6 +25893,7 @@ |
2129 | |
2130 | #. module: msf_doc_import |
2131 | #: view:wizard.import.batch:0 |
2132 | +#: view:msf.import.export:0 |
2133 | msgid "Run import" |
2134 | msgstr "Démarrer l'import" |
2135 | |
2136 | @@ -29743,7 +29780,13 @@ |
2137 | msgid "Total amount this customer owes you." |
2138 | msgstr "Montant Total Dû par ce Client." |
2139 | |
2140 | -#. modules: tender_flow, msf_partner, account, product, base, useability_dashboard_and_menu |
2141 | +#. modules: consumption_calculation, stock_override |
2142 | +#: report:addons/consumption_calculation/report/report_monthly_consumption_xls.mako:70 |
2143 | +#: field:export.report.stock.move,name:0 |
2144 | +msgid "Generated on" |
2145 | +msgstr "Generated on" |
2146 | + |
2147 | +#. modules: tender_flow, msf_partner, account, product, base, useability_dashboard_and_menu, msf_doc_import |
2148 | #: model:ir.ui.menu,name:account.menu_account_supplier |
2149 | #: model:ir.ui.menu,name:account.menu_finance_payables |
2150 | #: model:ir.actions.act_window,name:base.action_partner_supplier_form |
2151 | @@ -29755,6 +29798,7 @@ |
2152 | #: view:tender:0 |
2153 | #: field:tender,supplier_ids:0 |
2154 | #: model:ir.ui.menu,name:useability_dashboard_and_menu.menu_supplier |
2155 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:42 |
2156 | msgid "Suppliers" |
2157 | msgstr "Fournisseurs" |
2158 | |
2159 | @@ -30275,11 +30319,6 @@ |
2160 | msgid "Line %s. No info about given account: %s" |
2161 | msgstr "Line %s. No info about given account: %s" |
2162 | |
2163 | -#. module: account_hq_entries |
2164 | -#: model:ir.module.module,shortdesc:account_hq_entries.module_meta_information |
2165 | -msgid "HQ Entries" |
2166 | -msgstr "HQ Entries" |
2167 | - |
2168 | #. module: msf_budget |
2169 | #: view:wizard.budget.summary.export:0 |
2170 | msgid "Budget Summary PDF Export" |
2171 | @@ -30894,6 +30933,7 @@ |
2172 | |
2173 | #. module: msf_doc_import |
2174 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:308 |
2175 | +#: code:addons/msf_doc_import/msf_import_export.py:688 |
2176 | #, python-format |
2177 | msgid "(%s line(s) with warning - see warning messages below)" |
2178 | msgstr "(%s ligne(s) avec des avertissements - voir les avertissements ci-dessous)" |
2179 | @@ -32587,6 +32627,7 @@ |
2180 | |
2181 | #. module: msf_doc_import |
2182 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:313 |
2183 | +#: code:addons/msf_doc_import/msf_import_export.py:693 |
2184 | #, python-format |
2185 | msgid "no data will be imported until all the error messages are corrected" |
2186 | msgstr "aucune donnée ne sera importée tant que toutes les erreurs ne seront pas corrigées" |
2187 | @@ -35506,6 +35547,7 @@ |
2188 | |
2189 | #. module: msf_doc_import |
2190 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:298 |
2191 | +#: code:addons/msf_doc_import/msf_import_export.py:678 |
2192 | #, python-format |
2193 | msgid "Processing of file completed in %s second(s)!\n" |
2194 | "- Total lines to import: %s\n" |
2195 | @@ -36767,8 +36809,11 @@ |
2196 | msgid "Move state" |
2197 | msgstr "Statut de la transaction " |
2198 | |
2199 | -#. module: procurement_auto |
2200 | +#. modules: procurement_auto, procurement, msf_doc_import |
2201 | #: field:stock.warehouse.automatic.supply.line,supply_id:0 |
2202 | +#: field:stock.warehouse.orderpoint.line,supply_id:0 |
2203 | +#: model:ir.actions.act_window,name:msf_doc_import.msf_import_export_supply_action |
2204 | +#: model:ir.ui.menu,name:msf_doc_import.msf_import_export_supply_menu |
2205 | msgid "Supply" |
2206 | msgstr "Approvisionnement" |
2207 | |
2208 | @@ -40027,12 +40072,14 @@ |
2209 | msgid "DP execute" |
2210 | msgstr "DP execute" |
2211 | |
2212 | -#. modules: msf_instance, sync_so, account_hq_entries |
2213 | +#. modules: msf_instance, sync_so, account_hq_entries, account_hq_entries, msf_doc_import |
2214 | #: model:ir.actions.act_window,name:account_hq_entries.action_hq_entries_tree |
2215 | #: model:ir.model,name:account_hq_entries.model_hq_entries |
2216 | #: model:ir.ui.menu,name:account_hq_entries.menu_hq_entries |
2217 | #: view:res.company:0 |
2218 | #: model:ir.model,name:sync_so.model_hq_entries |
2219 | +#: model:ir.module.module,shortdesc:account_hq_entries.module_meta_information |
2220 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:81 |
2221 | msgid "HQ Entries" |
2222 | msgstr "Ecritures HQ" |
2223 | |
2224 | @@ -42744,6 +42791,7 @@ |
2225 | |
2226 | #. module: msf_doc_import |
2227 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:306 |
2228 | +#: code:addons/msf_doc_import/msf_import_export.py:686 |
2229 | #, python-format |
2230 | msgid "imported" |
2231 | msgstr "importées" |
2232 | @@ -42986,6 +43034,7 @@ |
2233 | |
2234 | #. module: msf_doc_import |
2235 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:306 |
2236 | +#: code:addons/msf_doc_import/msf_import_export.py:686 |
2237 | #, python-format |
2238 | msgid "without errors" |
2239 | msgstr "sans erreurs" |
2240 | @@ -48145,7 +48194,8 @@ |
2241 | msgid "Report can not be edited due to missing FX rates in specific currency table %s" |
2242 | msgstr "Report can not be edited due to missing FX rates in specific currency table %s" |
2243 | |
2244 | -#. module: base |
2245 | +#. modules: base, msf_doc_import |
2246 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:86 |
2247 | #: model:ir.actions.act_window,name:base.ir_access_act |
2248 | #: model:ir.ui.menu,name:base.menu_ir_access_act |
2249 | msgid "Access Controls List" |
2250 | @@ -50484,7 +50534,7 @@ |
2251 | msgid "Followup lines" |
2252 | msgstr "Suivi des Lignes" |
2253 | |
2254 | -#. modules: msf_budget, account, financing_contract, analytic_distribution |
2255 | +#. modules: msf_budget, account, financing_contract, analytic_distribution, msf_doc_import |
2256 | #: view:account.analytic.account:0 |
2257 | #: model:ir.ui.menu,name:account.account_analytic_def_account |
2258 | #: view:account.analytic.account:0 |
2259 | @@ -50492,6 +50542,7 @@ |
2260 | #: model:ir.ui.menu,name:financing_contract.menu_action_account_analytic_account_form |
2261 | #: view:account.analytic.account:0 |
2262 | #: model:ir.ui.menu,name:msf_budget.menu_action_account_analytic_account_budget_form |
2263 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:66 |
2264 | msgid "Analytic Accounts" |
2265 | msgstr "Comptes Analytiques" |
2266 | |
2267 | @@ -50610,7 +50661,7 @@ |
2268 | msgid "Read Access" |
2269 | msgstr "Accès Lecture" |
2270 | |
2271 | -#. modules: product_nomenclature, import_data, product_asset, kit |
2272 | +#. modules: product_nomenclature, import_data, product_asset, kit, msf_doc_import |
2273 | #: selection:import_data,object:0 |
2274 | #: selection:import_product,object:0 |
2275 | #: selection:update_product,object:0 |
2276 | @@ -50618,6 +50669,9 @@ |
2277 | #: field:product.asset,nomenclature_description:0 |
2278 | #: model:ir.model,name:product_nomenclature.model_product_nomenclature |
2279 | #: view:product.nomenclature:0 |
2280 | +#: selection:import_category,object:0 |
2281 | +#: selection:import_nomenclature,object:0 |
2282 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:32 |
2283 | msgid "Product Nomenclature" |
2284 | msgstr "Nomenclature du Produit" |
2285 | |
2286 | @@ -51151,7 +51205,7 @@ |
2287 | #: code:addons/msf_outgoing/wizard/validate_picking_processor.py:75 |
2288 | #, python-format |
2289 | msgid "Line %s: %s" |
2290 | -msgstr "Ligne %s: %s" |
2291 | +msgstr "Ligne %s : %s" |
2292 | |
2293 | #. module: account_override |
2294 | #: help:account.move.line,journal_type:0 |
2295 | @@ -52986,11 +53040,6 @@ |
2296 | msgid "Included Fields" |
2297 | msgstr "Champs Inclus" |
2298 | |
2299 | -#. module: kit |
2300 | -#: view:kit.mass.import:0 |
2301 | -msgid "Error messages" |
2302 | -msgstr "Error messages" |
2303 | - |
2304 | #. module: msf_partner |
2305 | #: view:res.partner:0 |
2306 | msgid "Customer LT" |
2307 | @@ -56414,13 +56463,14 @@ |
2308 | msgid "Choose Fiscal Year" |
2309 | msgstr "Choisir l'Exercice Comptable " |
2310 | |
2311 | -#. module: msf_field_access_rights |
2312 | +#. modules: msf_field_access_rights, msf_doc_import |
2313 | #: model:ir.actions.act_window,name:msf_field_access_rights.field_access_rule_line_list |
2314 | #: model:ir.ui.menu,name:msf_field_access_rights.field_access_rule_line_list_menu |
2315 | #: view:msf_field_access_rights.field_access_rule:0 |
2316 | #: field:msf_field_access_rights.field_access_rule,field_access_rule_line_ids:0 |
2317 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:119 |
2318 | msgid "Field Access Rule Lines" |
2319 | -msgstr "Field Access Rule Lines" |
2320 | +msgstr "Lignes de Règle d'Accès au Champs" |
2321 | |
2322 | #. module: analytic_distribution |
2323 | #: field:analytic.distribution.wizard,fp_line_ids:0 |
2324 | @@ -56584,11 +56634,12 @@ |
2325 | msgid "Manually corrected" |
2326 | msgstr "Manually corrected" |
2327 | |
2328 | -#. modules: account, account_mcdb |
2329 | +#. modules: account, account_mcdb, msf_doc_import |
2330 | #: view:account.analytic.journal:0 |
2331 | #: model:ir.actions.act_window,name:account.action_account_analytic_journal_form |
2332 | #: model:ir.ui.menu,name:account.account_def_analytic_journal |
2333 | #: view:account.mcdb:0 |
2334 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:71 |
2335 | msgid "Analytic Journals" |
2336 | msgstr "Journaux analytiques" |
2337 | |
2338 | @@ -56652,8 +56703,10 @@ |
2339 | msgid "In days" |
2340 | msgstr "En jours." |
2341 | |
2342 | -#. module: msf_doc_import |
2343 | +#. modules: msf_doc_import, kit |
2344 | +#: view:kit.mass.import:0 |
2345 | #: view:wizard.import.batch:0 |
2346 | +#: view:msf.import.export:0 |
2347 | msgid "Error messages" |
2348 | msgstr "Messages d'erreur" |
2349 | |
2350 | @@ -57560,9 +57613,10 @@ |
2351 | msgid "Action to Trigger" |
2352 | msgstr "Action à Déclencher" |
2353 | |
2354 | -#. module: base |
2355 | +#. modules: base, msf_doc_import |
2356 | #: model:ir.actions.act_window,name:base.ir_action_window |
2357 | #: model:ir.ui.menu,name:base.menu_ir_action_window |
2358 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:129 |
2359 | msgid "Window Actions" |
2360 | msgstr "Fenêtre Actions" |
2361 | |
2362 | @@ -58838,11 +58892,6 @@ |
2363 | msgid "Specific partner" |
2364 | msgstr "Partenaire spécifique" |
2365 | |
2366 | -#. module: procurement |
2367 | -#: field:stock.warehouse.orderpoint.line,supply_id:0 |
2368 | -msgid "Supply" |
2369 | -msgstr "Supply" |
2370 | - |
2371 | #. module: sale_override |
2372 | #: view:sale.order.line:0 |
2373 | msgid "This button shouldn't be use from form view. Please use the red cross on list view." |
2374 | @@ -60862,6 +60911,7 @@ |
2375 | #: selection:wizard.import.batch,state:0 |
2376 | #: view:automated.import.job:0 |
2377 | #: selection:automated.import.job,state:0 |
2378 | +#: selection:msf.import.export,state:0 |
2379 | #, python-format |
2380 | msgid "In progress" |
2381 | msgstr "En cours" |
2382 | @@ -61119,9 +61169,10 @@ |
2383 | msgid "%y - Year without century [00,99]." |
2384 | msgstr "%y - Année sans le siècle (00 à 99)." |
2385 | |
2386 | -#. module: base |
2387 | +#. modules: base, msf_doc_import |
2388 | #: model:ir.actions.act_window,name:base.action_rule |
2389 | #: model:ir.ui.menu,name:base.menu_action_rule |
2390 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:104 |
2391 | msgid "Record Rules" |
2392 | msgstr "Règles d´Enregistrement" |
2393 | |
2394 | @@ -61450,6 +61501,7 @@ |
2395 | #: code:addons/sale_override/sale.py:364 |
2396 | #: code:addons/sale_override/sale.py:365 |
2397 | #: code:addons/sale_override/sale.py:366 |
2398 | +#: selection:msf.import.export,state:0 |
2399 | #, python-format |
2400 | msgid "Not started" |
2401 | msgstr "Non démarré" |
2402 | @@ -61984,6 +62036,32 @@ |
2403 | msgid "Nothing to import" |
2404 | msgstr "Rien à importer" |
2405 | |
2406 | +#. modules: msf_budget, msf_homere_interface, supplier_catalogue, consumption_calculation, account_hq_entries, msf_doc_import, analytic_distribution, msf_doc_import, register_accounting |
2407 | +#: code:addons/account_hq_entries/wizard/hq_entries_import.py:319 |
2408 | +#: code:addons/analytic_distribution/wizard/import_commitment_wizard.py:72 |
2409 | +#: code:addons/consumption_calculation/wizard/wizard_import_fmc.py:87 |
2410 | +#: code:addons/consumption_calculation/wizard/wizard_import_rac.py:85 |
2411 | +#: code:addons/msf_budget/wizard/wizard_budget_import.py:240 |
2412 | +#: code:addons/msf_doc_import/composition_kit.py:86 |
2413 | +#: code:addons/msf_doc_import/composition_kit.py:181 |
2414 | +#: code:addons/msf_doc_import/initial_stock_inventory.py:92 |
2415 | +#: code:addons/msf_doc_import/initial_stock_inventory.py:600 |
2416 | +#: code:addons/msf_doc_import/stock_cost_reevaluation.py:51 |
2417 | +#: code:addons/msf_doc_import/tender.py:98 |
2418 | +#: code:addons/msf_doc_import/wizard/wizard_import_product_list.py:88 |
2419 | +#: code:addons/msf_doc_import/wizard/wizard_import_supplier_catalogue.py:164 |
2420 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:584 |
2421 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_import.py:479 |
2422 | +#: code:addons/supplier_catalogue/supplier_catalogue.py:590 |
2423 | +#: code:addons/supplier_catalogue/wizard/catalogue_import_lines.py:45 |
2424 | +#: code:addons/msf_doc_import/account.py:196 |
2425 | +#: code:addons/msf_doc_import/wizard/stock_partial_picking.py:254 |
2426 | +#: code:addons/msf_doc_import/wizard/stock_partial_picking.py:785 |
2427 | +#: code:addons/register_accounting/wizard/wizard_register_import.py:255 |
2428 | +#, python-format |
2429 | +msgid "Nothing to import." |
2430 | +msgstr "Rien à importer" |
2431 | + |
2432 | #. module: account_mcdb |
2433 | #: selection:account.mcdb,currency_choice:0 |
2434 | msgid "Booking" |
2435 | @@ -62406,6 +62484,7 @@ |
2436 | |
2437 | #. module: msf_doc_import |
2438 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:106 |
2439 | +#: code:addons/msf_doc_import/msf_import_export.py:364 |
2440 | #, python-format |
2441 | msgid "Import in progress, please leave this window open and press the button 'Update' to show the progression of the import. Otherwise, you can continue to use Unifield" |
2442 | msgstr "Traitement en cours, veuillez laisser cette fenêtre ouverte et cliquez sur le bouton 'Mettre à jour' pour voir la progression de l'import. Sinon, vous pouvez continuer d'utiliser Unifield" |
2443 | @@ -67248,6 +67327,8 @@ |
2444 | #: field:threshold.value,line_ids:0 |
2445 | #: field:threshold.value,product_ids:0 |
2446 | #: view:restrictive.country.setup:0 |
2447 | +#: view:product.list.line:0 |
2448 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:27 |
2449 | #, python-format |
2450 | msgid "Products" |
2451 | msgstr "Produits" |
2452 | @@ -68849,6 +68930,8 @@ |
2453 | #. module: msf_doc_import |
2454 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:286 |
2455 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:292 |
2456 | +#: code:addons/msf_doc_import/msf_import_export.py:666 |
2457 | +#: code:addons/msf_doc_import/msf_import_export.py:672 |
2458 | #, python-format |
2459 | msgid "Line %s: %s" |
2460 | msgstr "Ligne %s : %s" |
2461 | @@ -79938,6 +80021,7 @@ |
2462 | #: field:automated.import.job,state:0 |
2463 | #: field:export.report.inconsistencies,state:0 |
2464 | #: field:export.report.stopped.products,state:0 |
2465 | +#: field:msf.import.export,state:0 |
2466 | #: field:wizard.import.invoice.line,state:0 |
2467 | msgid "State" |
2468 | msgstr "État" |
2469 | @@ -80596,6 +80680,7 @@ |
2470 | |
2471 | #. module: msf_doc_import |
2472 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:170 |
2473 | +#: code:addons/msf_doc_import/msf_import_export.py:549 |
2474 | #, python-format |
2475 | msgid "Line seemed empty, so this line was ignored" |
2476 | msgstr "La ligne semblait vide, donc cette ligne a été ignorée" |
2477 | @@ -80655,7 +80740,7 @@ |
2478 | msgid "Send a test email" |
2479 | msgstr "Send a test email" |
2480 | |
2481 | -#. modules: tender_flow, product_nomenclature, product_asset, account_override, purchase_allocation_report, register_accounting, product_expiry, procurement_cycle, return_claim, supplier_catalogue, import_data, stock_schedule, unifield_setup, stock_forecast, stock_batch_recall, order_types, msf_doc_import, purchase_followup, product, stock_override, service_purchasing, consumption_calculation, purchase_override, specific_rules, kit, sale_override, product_list, product_manufacturer, procurement_report, threshold_value, purchase, account, msf_outgoing, stock_move_tracking, product_attributes, procurement_auto, sale, transport_mgmt, procurement, sourcing, msf_audittrail, purchase_msf, stock, sync_so |
2482 | +#. modules: tender_flow, product_nomenclature, product_asset, account_override, purchase_allocation_report, register_accounting, product_expiry, procurement_cycle, return_claim, supplier_catalogue, import_data, stock_schedule, unifield_setup, stock_forecast, stock_batch_recall, order_types, msf_doc_import, purchase_followup, product, stock_override, service_purchasing, consumption_calculation, purchase_override, specific_rules, kit, sale_override, product_list, product_manufacturer, procurement_report, threshold_value, purchase, account, msf_outgoing, stock_move_tracking, product_attributes, procurement_auto, sale, transport_mgmt, procurement, sourcing, msf_audittrail, purchase_msf, stock, sync_so, base |
2483 | #: field:account.analytic.line,product_id:0 |
2484 | #: view:account.entries.report:0 |
2485 | #: field:account.entries.report,product_id:0 |
2486 | @@ -80809,6 +80894,47 @@ |
2487 | #: field:threshold.value.line,product_id:0 |
2488 | #: model:ir.model,name:transport_mgmt.model_product_product |
2489 | #: model:ir.model,name:unifield_setup.model_product_product |
2490 | +#: report:allocation.invoices.report:0 |
2491 | +#: selection:res.request,ref_doc1:0 |
2492 | +#: selection:res.request,ref_doc2:0 |
2493 | +#: field:product.history.consumption.product,product_id:0 |
2494 | +#: selection:import_category,object:0 |
2495 | +#: selection:import_nomenclature,object:0 |
2496 | +#: report:kit.report:0 |
2497 | +#: report:addons/msf_doc_import/report/in_simulation_screen_xls_report.mako:149 |
2498 | +#: report:addons/msf_doc_import/report/in_simulation_screen_xls_report.mako:158 |
2499 | +#: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:230 |
2500 | +#: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:241 |
2501 | +#: report:po.simulation.screen:0 |
2502 | +#: field:product.product.import.line.qty,product_id:0 |
2503 | +#: field:wizard.import.in.line.simulation.screen,imp_product_id:0 |
2504 | +#: field:wizard.import.in.line.simulation.screen,move_product_id:0 |
2505 | +#: field:wizard.import.po.simulation.screen.line,imp_product_id:0 |
2506 | +#: field:wizard.import.po.simulation.screen.line,in_product_id:0 |
2507 | +#: view:create.picking.move.processor:0 |
2508 | +#: field:create.picking.move.processor,product_id:0 |
2509 | +#: view:internal.move.processor:0 |
2510 | +#: field:internal.move.processor,product_id:0 |
2511 | +#: view:outgoing.delivery.move.processor:0 |
2512 | +#: field:outgoing.delivery.move.processor,product_id:0 |
2513 | +#: view:ppl.move.processor:0 |
2514 | +#: field:ppl.move.processor,product_id:0 |
2515 | +#: view:return.ppl.move.processor:0 |
2516 | +#: field:return.ppl.move.processor,product_id:0 |
2517 | +#: view:stock.move.in.processor:0 |
2518 | +#: field:stock.move.in.processor,product_id:0 |
2519 | +#: view:stock.move.processor:0 |
2520 | +#: field:stock.move.processor,product_id:0 |
2521 | +#: view:validate.move.processor:0 |
2522 | +#: field:validate.move.processor,product_id:0 |
2523 | +#: field:stock.warehouse.orderpoint.line,product_id:0 |
2524 | +#: view:product.where.used:0 |
2525 | +#: field:product.where.used,product_id:0 |
2526 | +#: field:standard.price.track.changes,product_id:0 |
2527 | +#: field:account.direct.invoice.wizard.line,product_id:0 |
2528 | +#: field:unconsistent.stock.report.line,product_id:0 |
2529 | +#: view:stock.card.wizard:0 |
2530 | +#: field:stock.card.wizard,product_id:0 |
2531 | msgid "Product" |
2532 | msgstr "Produit" |
2533 | |
2534 | @@ -80902,7 +81028,7 @@ |
2535 | msgid "Select a supplier" |
2536 | msgstr "Sélectionner un fournisseur" |
2537 | |
2538 | -#. modules: msf_budget, purchase, account, msf_outgoing, account_payment, purchase_override, specific_rules, sale, base, register_accounting, msf_doc_import, return_claim, stock, analytic_distribution, msf_homere_interface |
2539 | +#. modules: msf_budget, purchase, account, msf_outgoing, account_payment, purchase_override, specific_rules, sale, base, register_accounting, msf_doc_import, return_claim, stock, analytic_distribution, delivery_mechanism, sales_followup, sync_client, tender_flow, sale_override, msf_tools, mission_stock, msf_homere_interface |
2540 | #: selection:account.invoice.report,state:0 |
2541 | #: selection:account.journal.period,state:0 |
2542 | #: selection:account.subscription,state:0 |
2543 | @@ -80947,6 +81073,30 @@ |
2544 | #: selection:stock.inventory,state:0 |
2545 | #: view:stock.move:0 |
2546 | #: view:stock.picking:0 |
2547 | +#: code:addons/delivery_mechanism/delivery_mechanism.py:1295 |
2548 | +#: code:addons/delivery_mechanism/delivery_mechanism.py:1315 |
2549 | +#: code:addons/delivery_mechanism/delivery_mechanism.py:1343 |
2550 | +#: code:addons/delivery_mechanism/delivery_mechanism.py:1388 |
2551 | +#: code:addons/mission_stock/wizard/mission_stock_wizard.py:48 |
2552 | +#: code:addons/mission_stock/wizard/mission_stock_wizard.py:56 |
2553 | +#: code:addons/msf_outgoing/msf_outgoing.py:3197 |
2554 | +#: view:automated.import.job:0 |
2555 | +#: selection:automated.import.job,state:0 |
2556 | +#: code:addons/sale_override/sale.py:176 |
2557 | +#: code:addons/sale_override/sale.py:371 |
2558 | +#: code:addons/sale_override/sale.py:372 |
2559 | +#: code:addons/sale_override/sale.py:377 |
2560 | +#: code:addons/sale_override/sale.py:378 |
2561 | +#: code:addons/sale_override/sale.py:1483 |
2562 | +#: code:addons/sale_override/sale.py:2035 |
2563 | +#: code:addons/sale_override/sale.py:2244 |
2564 | +#: code:addons/sale_override/sale.py:2506 |
2565 | +#: code:addons/sale_override/sale.py:2578 |
2566 | +#: view:sale.order.sourcing.progress:0 |
2567 | +#: selection:sale.followup.multi.wizard,state:0 |
2568 | +#: selection:sync.monitor,state:0 |
2569 | +#: selection:tender.line,line_state:0 |
2570 | +#: selection:msf.import.export,state:0 |
2571 | #: selection:wizard.import.invoice.line,state:0 |
2572 | #: selection:hr.payroll.validation,state:0 |
2573 | msgid "Done" |
2574 | @@ -83695,6 +83845,7 @@ |
2575 | |
2576 | #. module: msf_doc_import |
2577 | #: code:addons/msf_doc_import/wizard/wizard_import_batch.py:312 |
2578 | +#: code:addons/msf_doc_import/msf_import_export.py:692 |
2579 | #, python-format |
2580 | msgid "(see error messages below)" |
2581 | msgstr "(voir les erreurs ci-dessous)" |
2582 | @@ -84421,7 +84572,7 @@ |
2583 | #: code:addons/msf_doc_import/wizard/abstract_wizard_import.py:354 |
2584 | #, python-format |
2585 | msgid "Import can be run only on draft wizard." |
2586 | -msgstr "L'important ne peut être effectué que sur des assistants en état 'Non démarré'" |
2587 | +msgstr "L'importation ne peut être effectuée que sur des assistants en état 'Non démarré'" |
2588 | |
2589 | #. module: account_payment |
2590 | #: field:payment.line,currency:0 |
2591 | @@ -91108,6 +91259,7 @@ |
2592 | #: field:local.transport.cost.report,func_currency_id:0 |
2593 | #: field:local.transport.cost.report,transport_currency_id:0 |
2594 | #: field:purchase.order,transport_currency_id:0 |
2595 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:86 |
2596 | #: report:allocation.invoices.report:0 |
2597 | #: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:238 |
2598 | #: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:245 |
2599 | @@ -92693,51 +92845,6 @@ |
2600 | msgid "Patches marked as 'not-installed' must have an emission date" |
2601 | msgstr "Patches marked as 'not-installed' must have an emission date" |
2602 | |
2603 | -#. modules: register_accounting, msf_outgoing, product_attributes, import_data, stock_override, consumption_calculation, specific_rules, kit, account_override, procurement, base, msf_doc_import |
2604 | -#: report:allocation.invoices.report:0 |
2605 | -#: selection:res.request,ref_doc1:0 |
2606 | -#: selection:res.request,ref_doc2:0 |
2607 | -#: field:product.history.consumption.product,product_id:0 |
2608 | -#: selection:import_category,object:0 |
2609 | -#: selection:import_nomenclature,object:0 |
2610 | -#: report:kit.report:0 |
2611 | -#: report:addons/msf_doc_import/report/in_simulation_screen_xls_report.mako:149 |
2612 | -#: report:addons/msf_doc_import/report/in_simulation_screen_xls_report.mako:158 |
2613 | -#: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:230 |
2614 | -#: report:addons/msf_doc_import/report/po_simulation_screen_xls_report.mako:241 |
2615 | -#: report:po.simulation.screen:0 |
2616 | -#: field:product.product.import.line.qty,product_id:0 |
2617 | -#: field:wizard.import.in.line.simulation.screen,imp_product_id:0 |
2618 | -#: field:wizard.import.in.line.simulation.screen,move_product_id:0 |
2619 | -#: field:wizard.import.po.simulation.screen.line,imp_product_id:0 |
2620 | -#: field:wizard.import.po.simulation.screen.line,in_product_id:0 |
2621 | -#: view:create.picking.move.processor:0 |
2622 | -#: field:create.picking.move.processor,product_id:0 |
2623 | -#: view:internal.move.processor:0 |
2624 | -#: field:internal.move.processor,product_id:0 |
2625 | -#: view:outgoing.delivery.move.processor:0 |
2626 | -#: field:outgoing.delivery.move.processor,product_id:0 |
2627 | -#: view:ppl.move.processor:0 |
2628 | -#: field:ppl.move.processor,product_id:0 |
2629 | -#: view:return.ppl.move.processor:0 |
2630 | -#: field:return.ppl.move.processor,product_id:0 |
2631 | -#: view:stock.move.in.processor:0 |
2632 | -#: field:stock.move.in.processor,product_id:0 |
2633 | -#: view:stock.move.processor:0 |
2634 | -#: field:stock.move.processor,product_id:0 |
2635 | -#: view:validate.move.processor:0 |
2636 | -#: field:validate.move.processor,product_id:0 |
2637 | -#: field:stock.warehouse.orderpoint.line,product_id:0 |
2638 | -#: view:product.where.used:0 |
2639 | -#: field:product.where.used,product_id:0 |
2640 | -#: field:standard.price.track.changes,product_id:0 |
2641 | -#: field:account.direct.invoice.wizard.line,product_id:0 |
2642 | -#: field:unconsistent.stock.report.line,product_id:0 |
2643 | -#: view:stock.card.wizard:0 |
2644 | -#: field:stock.card.wizard,product_id:0 |
2645 | -msgid "Product" |
2646 | -msgstr "Product" |
2647 | - |
2648 | #. module: report_webkit |
2649 | #: view:ir.header_webkit:0 |
2650 | msgid "Content and styling" |
2651 | @@ -92870,7 +92977,7 @@ |
2652 | msgid "SQL Constraint" |
2653 | msgstr "Contrainte SQL" |
2654 | |
2655 | -#. modules: hr, base, msf_homere_interface |
2656 | +#. modules: hr, base, msf_homere_interface, msf_doc_import |
2657 | #: model:ir.actions.act_window,name:base.action_partner_employee_form |
2658 | #: view:hr.employee:0 |
2659 | #: field:hr.job,employee_ids:0 |
2660 | @@ -92880,6 +92987,7 @@ |
2661 | #: model:ir.ui.menu,name:hr.menu_open_view_employee_list_my |
2662 | #: model:ir.ui.menu,name:hr.menu_view_employee_category_configuration_form |
2663 | #: view:hr.employee:0 |
2664 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:76 |
2665 | msgid "Employees" |
2666 | msgstr "Employé(e)s" |
2667 | |
2668 | @@ -95260,11 +95368,11 @@ |
2669 | msgid "GRAND TOTAL" |
2670 | msgstr "GRAND TOTAL" |
2671 | |
2672 | -#. module: msf_field_access_rights |
2673 | +#. module: msf_field_access_right |
2674 | #: model:ir.model,name:msf_field_access_rights.model_msf_field_access_rights_field_access_rule_line |
2675 | #: view:msf_field_access_rights.field_access_rule_line:0 |
2676 | msgid "Field Access Rule Line" |
2677 | -msgstr "Field Access Rule Line" |
2678 | +msgstr "Ligne de Règle d'Accès au Champs" |
2679 | |
2680 | #. module: account_mcdb |
2681 | #: view:account.mcdb:0 |
2682 | @@ -98029,6 +98137,166 @@ |
2683 | msgid "Article must be used only in a properly designed programme, need a more detailed description." |
2684 | msgstr "L'article doit être uniquement utilisé dans un programme correctement construit, à besoin d'une description plus détaillée." |
2685 | |
2686 | +#. module: msf_doc_import |
2687 | +#: model:ir.actions.report.xml,name:msf_doc_import.wizard_export_generic |
2688 | +msgid "Generic Export" |
2689 | +msgstr "Export Générique" |
2690 | + |
2691 | +#. module: msf_doc_import |
2692 | +#: field:msf.import.export,model_list_selection:0 |
2693 | +msgid "Object to Import/Export" |
2694 | +msgstr "Objet à Importer/Exporter" |
2695 | + |
2696 | +#. module: msf_doc_import |
2697 | +#: field:msf.import.export,import_file:0 |
2698 | +msgid "File to import .xml" |
2699 | +msgstr "Fichier à importer .xml" |
2700 | + |
2701 | +#. module: msf_doc_import |
2702 | +#: code:addons/msf_doc_import/msf_import_export.py:93 |
2703 | +#, python-format |
2704 | +msgid "%s_Import_Template" |
2705 | +msgstr "%s_Modèle_d_import" |
2706 | + |
2707 | +#. module: msf_doc_import |
2708 | +#: code:addons/msf_doc_import/msf_import_export.py:198 |
2709 | +#: code:addons/msf_doc_import/msf_import_export.py:322 |
2710 | +#, python-format |
2711 | +msgid "field '%s' not found for model '%s'. Please contact the support team." |
2712 | +msgstr "champ '%s' non trouvé pour le modèle '%s'. Veuillez contacter l'équipe support." |
2713 | + |
2714 | +#. module: msf_doc_import |
2715 | +#: code:addons/msf_doc_import/msf_import_export.py:112 |
2716 | +#, python-format |
2717 | +msgid "Selection '%s' not found. Please contact the support team." |
2718 | +msgstr "Sélection '%s' non trouvée. Veuillez contacter l'équipe support." |
2719 | + |
2720 | +#. module: msf_doc_import |
2721 | +#: code:addons/msf_doc_import/msf_import_export.py:117 |
2722 | +#, python-format |
2723 | +msgid "The header_list for report '%s' is not defined. Please contact the support team." |
2724 | +msgstr "La liste des entêtes pour le rapport '%s' n'est pas définie. Veuillez contacter l'équipe support." |
2725 | + |
2726 | +#. module: msf_doc_import |
2727 | +#: code:addons/msf_doc_import/msf_import_export.py:264 |
2728 | +#, python-format |
2729 | +msgid "File structure is incorrect, please correct. You may generate a template with the File export functionality." |
2730 | +msgstr "La structure du fichier est incorrecte, veuillez corriger. Vous pouvez générer un modèle avec la fonctionnalité d'exportation de modèle." |
2731 | + |
2732 | +#. module: msf_doc_import |
2733 | +#: code:addons/msf_doc_import/msf_import_export.py:272 |
2734 | +#, python-format |
2735 | +msgid "File structure is correct." |
2736 | +msgstr "La structure du fichier est correcte." |
2737 | + |
2738 | +#. module: msf_doc_import |
2739 | +#: code:addons/msf_doc_import/msf_import_export.py:325 |
2740 | +#, python-format |
2741 | +msgid "Column %s: get '%s' expected '%s'." |
2742 | +msgstr "Colonne %s: reçu '%s' attendu '%s'." |
2743 | + |
2744 | +#. module: msf_doc_import |
2745 | +#: code:addons/msf_doc_import/msf_import_export.py:328 |
2746 | +#, python-format |
2747 | +msgid "The following columns are missing in the imported file:\n" |
2748 | +"%s" |
2749 | +msgstr "Les colonnes suivantes sont manquantes dans le fichier importé :\n" |
2750 | +"%s" |
2751 | + |
2752 | +#. module: msf_doc_import |
2753 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:37 |
2754 | +#, python-format |
2755 | +msgid "Product Categories" |
2756 | +msgstr "Catégories Produit" |
2757 | + |
2758 | +#. module: msf_doc_import |
2759 | +#: model:ir.actions.act_window,name:msf_doc_import.msf_import_export_non_functional_action |
2760 | +#: model:ir.ui.menu,name:msf_doc_import.msf_import_export_non_functional_menu |
2761 | +msgid "Non Functional" |
2762 | +msgstr "Non Functionnel" |
2763 | + |
2764 | +#. module: msf_doc_import |
2765 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:48 |
2766 | +#, python-format |
2767 | +msgid "Supplier Catalogues" |
2768 | +msgstr "Catalogues Fournisseur" |
2769 | + |
2770 | +#. module: msf_doc_import |
2771 | +#: view:msf.import.export:0 |
2772 | +#: field:msf.import.export,display_file_import:0 |
2773 | +msgid "File Import" |
2774 | +msgstr "Import Fichier" |
2775 | + |
2776 | +#. module: msf_doc_import |
2777 | +#: view:msf.import.export:0 |
2778 | +#: field:msf.import.export,display_file_export:0 |
2779 | +msgid "File Export" |
2780 | +msgstr "Export Fichier" |
2781 | + |
2782 | +#. module: msf_doc_import |
2783 | +#: view:msf.import.export:0 |
2784 | +msgid "Export empty template" |
2785 | +msgstr "Exporter un modèle vide" |
2786 | + |
2787 | +#. module: msf_doc_import |
2788 | +#: view:msf.import.export:0 |
2789 | +msgid "Export first 3 entries" |
2790 | +msgstr "Exporter les 3 premières entrées" |
2791 | + |
2792 | +#. module: msf_doc_import |
2793 | +#: view:msf.import.export:0 |
2794 | +msgid "Export all data" |
2795 | +msgstr "Exporter toutes les données" |
2796 | + |
2797 | +#. module: msf_doc_import |
2798 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:56 |
2799 | +#, python-format |
2800 | +msgid "GL Accounts" |
2801 | +msgstr "Comptes" |
2802 | + |
2803 | +#. module: msf_doc_import |
2804 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:61 |
2805 | +#, python-format |
2806 | +msgid "GL Journals" |
2807 | +msgstr "Journaux" |
2808 | + |
2809 | +#. module: msf_doc_import |
2810 | +#: view:msf.import.export:0 |
2811 | +msgid "Test file" |
2812 | +msgstr "Tester le fichier" |
2813 | + |
2814 | +#. module: msf_doc_import |
2815 | +#: view:msf.import.export:0 |
2816 | +#: view:wizard.import.batch:0 |
2817 | +msgid "Download template file" |
2818 | +msgstr "Télécharger un fichier modèle" |
2819 | + |
2820 | +#. module: msf_homere_interface |
2821 | +#: code:addons/msf_homere_interface/hr.py:137 |
2822 | +#, python-format |
2823 | +msgid "Some employees have the same unique code: %s" |
2824 | +msgstr "Certains employés ont le même code unique : %s" |
2825 | + |
2826 | +#. modules: msf_doc_import |
2827 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:86 |
2828 | +msgid "Currency" |
2829 | +msgstr "Devise" |
2830 | + |
2831 | +#. modules: msf_doc_import |
2832 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:99 |
2833 | +msgid "User Access" |
2834 | +msgstr "Accès utilisateur" |
2835 | + |
2836 | +#. modules: msf_doc_import |
2837 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:99 |
2838 | +msgid "User Groups" |
2839 | +msgstr "Groupes utilisateur" |
2840 | + |
2841 | +#. modules: msf_doc_import |
2842 | +#: code:addons/msf_doc_import/msf_import_export_conf.py:99 |
2843 | +msgid "Currencies Rates" |
2844 | +msgstr "Taux des Devises" |
2845 | + |
2846 | #. module: account |
2847 | #: code:addons/account/report/common_report_header.py:136 |
2848 | #, python-format |
2849 | @@ -98661,6 +98929,37 @@ |
2850 | msgid "Warning, you have removed header value source location! The lines will be re-set to have 'Other Supplier' as the source location. Please check this is correct!" |
2851 | msgstr "Attention, vous avez supprimé la zone source d'en-tête! La zone source des lignes va être réinitialisée avec la valeur 'Autre Fournisseur'. Merci de vérifier leur cohérence!" |
2852 | |
2853 | +#. module: msf_doc_import |
2854 | +#: field:msf.import.export,csv_button:0 |
2855 | +msgid "Import from CSV" |
2856 | +msgstr "Importer depuis un fichier CSV" |
2857 | + |
2858 | +#. module: msf_doc_import |
2859 | +#: field:msf.import.export,display_import_buttons:0 |
2860 | +msgid "Display import buttons" |
2861 | +msgstr "Afficher les boutons d'import" |
2862 | + |
2863 | +#. module: msf_doc_import |
2864 | +#: code:addons/msf_doc_import/msf_import_export.py:415 |
2865 | +#: code:addons/msf_doc_import/msf_import_export.py:429 |
2866 | +#, python-format |
2867 | +msgid "Import in progress in the specific wizard." |
2868 | +msgstr "Import en cours dans l'assistant spécifique." |
2869 | + |
2870 | +#. module: msf_doc_import |
2871 | +#: code:addons/msf_doc_import/msf_import_export.py:434 |
2872 | +#, python-format |
2873 | +msgid "The model '%s' is not made to be imported in CSV file.\n" |
2874 | +"Please contact the support team." |
2875 | +msgstr "Le model '%s' n'est pas fait pour être imorté en fichier CSV.\n" |
2876 | +"Veuillez contacter léquipe support." |
2877 | + |
2878 | +#. module: msf_doc_import |
2879 | +#: code:addons/msf_doc_import/msf_import_export.py:439 |
2880 | +#, python-format |
2881 | +msgid "Import has been done via the specific wizard. The latter had to give information on the import." |
2882 | +msgstr "L'import à été fait via l'assistant spécifique. Ce dernier à dû donnner les information concernant l'import." |
2883 | + |
2884 | #. module: account_override |
2885 | #: code:addons/account_override/account.py:524 |
2886 | #, python-format |
2887 | |
2888 | === modified file 'bin/addons/product_nomenclature/product_nomenclature.py' |
2889 | --- bin/addons/product_nomenclature/product_nomenclature.py 2017-05-29 14:06:25 +0000 |
2890 | +++ bin/addons/product_nomenclature/product_nomenclature.py 2017-09-27 13:17:20 +0000 |
2891 | @@ -821,7 +821,7 @@ |
2892 | 4. duplication from GUI: the default code XXX is saved, then modify in the write |
2893 | ''' |
2894 | # The first 2 cases: dup of default_code/xmlid_code not allow |
2895 | - if context.get('from_import_menu') or context.get('sync_update_execution', False): |
2896 | + if context.get('sync_update_execution', False): |
2897 | if not default_code or not vals.get('xmlid_code', False): |
2898 | raise Exception, "Problem creating product: Missing xmlid_code/default_code in the data" |
2899 | if not vals.get('xmlid_code'): |
2900 | |
2901 | === modified file 'bin/addons/res_currency_tables/wizard/import_currencies.py' |
2902 | --- bin/addons/res_currency_tables/wizard/import_currencies.py 2017-03-17 13:33:26 +0000 |
2903 | +++ bin/addons/res_currency_tables/wizard/import_currencies.py 2017-09-27 13:17:20 +0000 |
2904 | @@ -92,6 +92,10 @@ |
2905 | # Some checks |
2906 | if context is None: |
2907 | context = {} |
2908 | + |
2909 | + if isinstance(ids, (int, long)): |
2910 | + ids = [ids] |
2911 | + |
2912 | # Prepare some values |
2913 | currency_obj = self.pool.get('res.currency') |
2914 | currency_rate_obj = self.pool.get('res.currency.rate') |
2915 | |
2916 | === modified file 'bin/osv/orm.py' |
2917 | --- bin/osv/orm.py 2017-08-18 14:26:52 +0000 |
2918 | +++ bin/osv/orm.py 2017-09-27 13:17:20 +0000 |
2919 | @@ -675,10 +675,18 @@ |
2920 | elif f[i] in self._inherit_fields.keys(): |
2921 | cols = selection_field(self._inherits) |
2922 | if cols and cols._type == 'selection' and not sync_context: |
2923 | - sel_list = cols.selection |
2924 | - if r and type(sel_list) == type([]): |
2925 | - r = [x[1] for x in sel_list if r==x[0]] |
2926 | - r = r and r[0] or False |
2927 | + # if requested, translate the fields.selection values |
2928 | + translated_selection = False |
2929 | + if context.get('translate_selection_field', False) and r and f: |
2930 | + fields_get_res = self.fields_get(cr, uid, f, context=context) |
2931 | + if f[0] in fields_get_res and 'selection' in fields_get_res[f[0]]: |
2932 | + r = dict(fields_get_res[f[0]]['selection'])[r] |
2933 | + translated_selection = True |
2934 | + if not translated_selection: |
2935 | + sel_list = cols.selection |
2936 | + if r and type(sel_list) == type([]): |
2937 | + r = [x[1] for x in sel_list if r==x[0]] |
2938 | + r = r and r[0] or False |
2939 | if not r: |
2940 | if f[i] in self._columns: |
2941 | r = check_type(self._columns[f[i]]._type) |
On Monday 10 April 2017 14:54:10 you wrote: size_from_ string( self, string): len(string) *(3/4.) +15)
> > + def get_excel_
> > + """Compute the string to get the size of it in a excel
> > + understandable value
> > + :param string: the str chain to get the excel size
> > + :return: A int instance
> > + """
> > + # this complex calculation is used to translate the
> > + # character len to an excel understandable len
> > + size = round(7*
>
> Please explain the heuristic here.
fixed here : http:// bazaar. launchpad. net/~fabien- morin/unifield- server/ fm-us-2619/ revision/ 4318
--
Fabien MORIN
TeMPO Consulting
20, avenue de la Paix
67000 Strasbourg
France
http:// www.tempo- consulting. fr
Tel : +33 3 88 56 82 16
Fax : +33 9 70 63 35 46