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