From e77abb81fe3af1bad710a199b5aeb4b684754518 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 10 Nov 2011 16:46:14 +0100 Subject: [PATCH 001/612] [IMP] Use babel's locale-aware date formatting when formatting dates in read_group titles bzr revid: xmo@openerp.com-20111110154614-ok0i1w11xvace41y --- openerp/osv/orm.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index a89074d322d..a93f4f4a620 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -54,6 +54,8 @@ import time import traceback import types import warnings + +import babel.dates from lxml import etree import fields @@ -2471,7 +2473,9 @@ class BaseModel(object): dt = datetime.datetime.strptime(alldata[d['id']][groupby][:7], '%Y-%m') days = calendar.monthrange(dt.year, dt.month)[1] - d[groupby] = datetime.datetime.strptime(d[groupby][:10], '%Y-%m-%d').strftime('%B %Y') + date_value = datetime.datetime.strptime(d[groupby][:10], '%Y-%m-%d') + d[groupby] = babel.dates.format_date( + date_value, format='MMMM yyyy', locale=context.get('lang', 'en_US')) d['__domain'] = [(groupby, '>=', alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-01', '%Y-%m-%d').strftime('%Y-%m-%d') or False),\ (groupby, '<=', alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-' + str(days), '%Y-%m-%d').strftime('%Y-%m-%d') or False)] + domain del alldata[d['id']][groupby] From 63ee6a74a91a630f5b5049f10ae67291df85f760 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 9 Jul 2012 17:09:54 +0530 Subject: [PATCH 002/612] [IMP] project : column project_task_history_cumulative.project_id does not exist. lp bug: https://launchpad.net/bugs/1022509 fixed bzr revid: mdi@tinyerp.com-20120709113954-l17wlurxovz6z05i --- addons/project/report/project_cumulative.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/addons/project/report/project_cumulative.xml b/addons/project/report/project_cumulative.xml index 3f7f3b26d96..535fbaf5f87 100644 --- a/addons/project/report/project_cumulative.xml +++ b/addons/project/report/project_cumulative.xml @@ -9,7 +9,6 @@ - @@ -63,9 +62,7 @@ - - From e2ba0eb95c38a16839836deeaa9a73b58221e9aa Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 9 Jul 2012 18:42:59 +0530 Subject: [PATCH 003/612] [IMP] project : Revert the unneccessary changes. bzr revid: mdi@tinyerp.com-20120709131259-c9fl7g3hgwhxutgb --- addons/project/report/project_cumulative.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/project/report/project_cumulative.xml b/addons/project/report/project_cumulative.xml index 535fbaf5f87..177e945bc93 100644 --- a/addons/project/report/project_cumulative.xml +++ b/addons/project/report/project_cumulative.xml @@ -9,6 +9,7 @@ + From f9ad472466645f8ab9dc4dbc66a049042d97b8f9 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 11 Jul 2012 12:40:54 +0530 Subject: [PATCH 004/612] [ADD] add new http service translation. bzr revid: tpa@tinyerp.com-20120711071054-rfreaxwys8b1fqbc --- openerp/service/web_services.py | 50 +++++++++++++++++++++++++++++++++ openerp/tools/translate.py | 17 +++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 330bb86dcfc..6762426d8cd 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -777,6 +777,55 @@ class report_spool(netsvc.ExportService): else: raise Exception, 'ReportNotFound' +class translation(netsvc.ExportService): + + def __init__(self, name="translation"): + netsvc.ExportService.__init__(self, name) + + def exp_load(self, db, modules, langs, flag=None, context=None): + translated_data = [] + cr = pooler.get_db(db).cursor() + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + cr.commit() + cr.close() + return translated_data + + def dispatch(self, method, params): + if method in ['load']: + # No security check for these methods + pass + else: + raise KeyError("Method not found: %s" % method) + fn = getattr(self, 'exp_'+method) + return fn(*params) + +translation() def start_web_services(): db() @@ -784,6 +833,7 @@ def start_web_services(): objects_proxy() wizard() report_spool() + translation() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index eb5dbe24077..0d3802bd5c0 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -43,6 +43,7 @@ import misc from misc import UpdateableStr from misc import SKIPPED_ELEMENT_TYPES import osutil +import babel.messages.pofile _logger = logging.getLogger(__name__) @@ -842,12 +843,22 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): try: fileobj = misc.file_open(filename) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + if flag == 'web': + transl = {"messages":[]} + po = babel.messages.pofile.read_po(fileobj) + for x in po: + if x.id and x.string and "openerp-web" in x.auto_comments: + transl["messages"].append({'id': x.id, 'string': x.string}) + return transl + else: + fileformat = os.path.splitext(filename)[-1][1:].lower() + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) fileobj.close() return r except IOError: From 67aa9fa31a7c64bf59a1b942ecbe6dc83c878241 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 11 Jul 2012 12:44:05 +0530 Subject: [PATCH 005/612] [IMP] load translation using 'translation' http service bzr revid: tpa@tinyerp.com-20120711071405-g0biuqlctedlbcs9 --- addons/web/controllers/main.py | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 412ea9abda2..5d7aa93f3a5 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -353,25 +353,15 @@ class WebClient(openerpweb.Controller): langs = lang.split(separator) langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)] - transs = {} - for addon_name in mods: - transl = {"messages":[]} - transs[addon_name] = transl - addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] - for l in langs: - f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") - if not os.path.exists(f_name): - continue - try: - with open(f_name) as t_file: - po = babel.messages.pofile.read_po(t_file) - except Exception: - continue - for x in po: - if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) - return {"modules": transs, - "lang_parameters": lang_obj} + messages = {} + for mod in mods: + messages[mod] = {"messages":[]} + proxy = req.session.proxy("translation") + trans = proxy.load(req.session._db, [mod], langs, "web") + if trans: + messages[mod] = trans + return {"modules": {'messages': messages}, + "lang_parameters": lang_obj} @openerpweb.jsonrequest def version_info(self, req): From 4ea3ad65b24ad8b89d1c06d36bffc40e3ea9a865 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 10:51:11 +0530 Subject: [PATCH 006/612] [ADD] added module field in ir.translation and improved code for that. bzr revid: tpa@tinyerp.com-20120712052111-5qq9noxd5vd9dlwv --- openerp/addons/base/ir/ir_translation.py | 20 ++++++++++---------- openerp/addons/base/module/module.py | 4 ++-- openerp/service/web_services.py | 4 ++-- openerp/tools/translate.py | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 61e40e807d4..2f8f87a0a2a 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -70,7 +70,6 @@ class ir_translation_import_cursor(object): cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), - imd_module VARCHAR(64), imd_name VARCHAR(128) ) INHERITS (%s) ''' % (self._table_name, self._parent_table)) @@ -80,10 +79,10 @@ class ir_translation_import_cursor(object): self._cr.execute("INSERT INTO " + self._table_name \ + """(name, lang, res_id, src, type, - imd_model, imd_module, imd_name, value) + imd_model, module, imd_name, value) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", (ddict['name'], ddict['lang'], ddict.get('res_id'), ddict['src'], ddict['type'], - ddict.get('imd_model'), ddict.get('imd_module'), ddict.get('imd_name'), + ddict.get('imd_model'), ddict.get('module'), ddict.get('imd_name'), ddict['value'])) def finish(self): @@ -101,18 +100,18 @@ class ir_translation_import_cursor(object): SET res_id = imd.res_id FROM ir_model_data AS imd WHERE ti.res_id IS NULL - AND ti.imd_module IS NOT NULL AND ti.imd_name IS NOT NULL + AND ti.module IS NOT NULL AND ti.imd_name IS NOT NULL - AND ti.imd_module = imd.module AND ti.imd_name = imd.name + AND ti.module = imd.module AND ti.imd_name = imd.name AND ti.imd_model = imd.model; """ % self._table_name) if self._debug: - cr.execute("SELECT imd_module, imd_model, imd_name FROM %s " \ - "WHERE res_id IS NULL AND imd_module IS NOT NULL" % self._table_name) + cr.execute("SELECT module, imd_model, imd_name FROM %s " \ + "WHERE res_id IS NULL AND module IS NOT NULL" % self._table_name) for row in cr.fetchall(): _logger.debug("ir.translation.cursor: missing res_id for %s. %s/%s ", *row) - cr.execute("DELETE FROM %s WHERE res_id IS NULL AND imd_module IS NOT NULL" % \ + cr.execute("DELETE FROM %s WHERE res_id IS NULL AND module IS NOT NULL" % \ self._table_name) # Records w/o res_id must _not_ be inserted into our db, because they are @@ -132,8 +131,8 @@ class ir_translation_import_cursor(object): # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value) - SELECT name, lang, res_id, src, type, value + cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module) + SELECT name, lang, res_id, src, type, value, module FROM %s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); """ % (self._parent_table, self._table_name, self._parent_table, find_expr)) @@ -167,6 +166,7 @@ class ir_translation(osv.osv): 'type': fields.selection(TRANSLATION_TYPE, string='Type', size=16, select=True), 'src': fields.text('Source'), 'value': fields.text('Translation Value'), + 'module': fields.char('Module Name', size=128), } _sql_constraints = [ ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)', diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 392850f7b77..1a3b41513b4 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -620,7 +620,7 @@ class module(osv.osv): f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, context=context) + tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -630,7 +630,7 @@ class module(osv.osv): f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, context=context2) + tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 6762426d8cd..2dbaa67a425 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -799,7 +799,7 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +809,7 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 0d3802bd5c0..83576d8d7b9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -843,7 +843,7 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) pool = pooler.get_pool(cr.dbname) @@ -858,7 +858,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() return r except IOError: @@ -866,7 +866,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): _logger.error("couldn't read translation file %s", filename) return None -def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, context=None): +def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None): """Populates the ir_translation table.""" if verbose: _logger.info('loading translation file for language %s', lang) @@ -896,7 +896,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, break elif fileformat == 'po': reader = TinyPoFile(fileobj) - f = ['type', 'name', 'res_id', 'src', 'value'] + f = ['type', 'name', 'res_id', 'src', 'value', 'module'] else: _logger.error('Bad file format: %s', fileformat) raise Exception(_('Bad file format')) @@ -929,6 +929,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if res_id and isinstance(res_id, (int, long)) \ or (isinstance(res_id, basestring) and res_id.isdigit()): dic['res_id'] = int(res_id) + dic['module'] = module_name else: try: tmodel = dic['name'].split(',')[0] @@ -938,9 +939,8 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, tmodule = dic_module tname = res_id dic['imd_model'] = tmodel - dic['imd_module'] = tmodule + dic['module'] = tmodule dic['imd_name'] = tname - dic['res_id'] = None except Exception: _logger.warning("Could not decode resource for %s, please fix the po file.", From d87adc497e11e3f5c22da7069720b6f9270d7ada Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 14:28:38 +0530 Subject: [PATCH 007/612] [IMP] improved code to get translation from database. bzr revid: tpa@tinyerp.com-20120712085838-pqzj86fptp96eag6 --- openerp/service/web_services.py | 10 +++++++--- openerp/tools/translate.py | 13 ++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 2dbaa67a425..7f6b201d9c3 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,7 +783,7 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = [] + translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() for module_name in modules: modpath = openerp.modules.get_module_path(module_name) @@ -799,7 +799,9 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +811,9 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 83576d8d7b9..4067133e2a9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,12 +849,11 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web': - transl = {"messages":[]} - po = babel.messages.pofile.read_po(fileobj) - for x in po: - if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) + if flag == 'web' and module_name == 'web': + transl = [] + trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) + for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): + transl.append({'id': trans.src, 'string': trans.value}) return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() @@ -913,7 +912,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, # dictionary which holds values for this line of the csv file # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ..., - # 'src': ..., 'value': ...} + # 'src': ..., 'value': ..., 'module':...} dic = {'lang': lang} dic_module = False for i in range(len(f)): From 20646e9104a1e36a2375f0b688dc5a5ed18665b1 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:01:30 +0530 Subject: [PATCH 008/612] [IMP] move load function to the ir_translation.py bzr revid: tpa@tinyerp.com-20120712093130-rcis1aamb7bbptdd --- openerp/addons/base/ir/ir_translation.py | 36 ++++++++++++++++++++++++ openerp/service/web_services.py | 35 ++--------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 2f8f87a0a2a..404dfb842a3 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -22,6 +22,7 @@ from osv import fields, osv import tools import logging +import openerp.modules _logger = logging.getLogger(__name__) @@ -322,6 +323,41 @@ class ir_translation(osv.osv): """ Return a cursor-like object for fast inserting translations """ return ir_translation_import_cursor(cr, uid, self, context=context) + + def load(self, cr, modules, langs, flag, context=None): + translated_data = {'messages':[]} + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + return translated_data ir_translation() diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 7f6b201d9c3..17935efda54 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,39 +783,10 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() - for module_name in modules: - modpath = openerp.modules.get_module_path(module_name) - if not modpath: - # unable to find the module. we skip - continue - for lang in langs: - iso_lang = tools.get_iso_codes(lang) - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') + translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data From 976944bce2f4a39f0d1f0b22737a2b0603479b32 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:21:31 +0530 Subject: [PATCH 009/612] [IMP] improved code in module.py to load translation. bzr revid: tpa@tinyerp.com-20120712095131-3tt25snidvafflhb --- openerp/addons/base/ir/ir_translation.py | 2 +- openerp/addons/base/module/module.py | 30 +++--------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 404dfb842a3..ad7d7013127 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -324,7 +324,7 @@ class ir_translation(osv.osv): """ return ir_translation_import_cursor(cr, uid, self, context=context) - def load(self, cr, modules, langs, flag, context=None): + def load(self, cr, modules, langs, flag=None, context=None): translated_data = {'messages':[]} for module_name in modules: modpath = openerp.modules.get_module_path(module_name) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 1a3b41513b4..963fb292946 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -596,8 +596,8 @@ class module(osv.osv): def update_translations(self, cr, uid, ids, filter_lang=None, context=None): if context is None: context = {} + pool = pooler.get_pool(cr.dbname) if not filter_lang: - pool = pooler.get_pool(cr.dbname) lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) filter_lang = [lang.code for lang in lang_obj.browse(cr, uid, lang_ids)] @@ -607,32 +607,8 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - modpath = modules.get_module_path(mod.name) - if not modpath: - # unable to find the module. we skip - continue - for lang in filter_lang: - iso_lang = tools.get_iso_codes(lang) - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) + traslation_obj = pool.get('ir.translation') + traslation_obj.load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): From f0f4ba6d413ce89e016b26895f1e3fb62450d2ae Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 16:11:10 +0530 Subject: [PATCH 010/612] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120712104110-wot1evq0affpx2tp --- addons/web/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 5d7aa93f3a5..eb60b178ad2 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -360,7 +360,7 @@ class WebClient(openerpweb.Controller): trans = proxy.load(req.session._db, [mod], langs, "web") if trans: messages[mod] = trans - return {"modules": {'messages': messages}, + return {"modules": messages, "lang_parameters": lang_obj} @openerpweb.jsonrequest From 4bbbef1929fc41b9928690ac77112ec5aa3db452 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 16:29:55 +0530 Subject: [PATCH 011/612] [IMP] improved code for load translation when run web without embedded mode. bzr revid: tpa@tinyerp.com-20120712105955-szwm5vb49va6o4dp --- addons/web/controllers/main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index eb60b178ad2..75feed44c69 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -360,6 +360,24 @@ class WebClient(openerpweb.Controller): trans = proxy.load(req.session._db, [mod], langs, "web") if trans: messages[mod] = trans + # keep loading from .po (Reason to run web without embedded mode) + if not messages['web']['messages']: + for addon_name in mods: + transl = {'messages':[]} + messages[addon_name] = transl + addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] + for l in langs: + f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") + if not os.path.exists(f_name): + continue + try: + with open(f_name) as t_file: + po = babel.messages.pofile.read_po(t_file) + except Exception: + continue + for x in po: + if x.id and x.string and "openerp-web" in x.auto_comments: + transl["messages"].append({'id': x.id, 'string': x.string}) return {"modules": messages, "lang_parameters": lang_obj} From bc76991e24edc42353fc637624fa7ff4bfa8a34f Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:53:08 +0530 Subject: [PATCH 012/612] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120712132308-1qvurv572sxmsnqe --- openerp/addons/base/ir/ir_translation.py | 8 ++------ openerp/tools/translate.py | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index ad7d7013127..0a3124b36ce 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -340,9 +340,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -352,9 +350,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 4067133e2a9..517b39e6999 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -857,9 +857,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) + trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return r + return [] except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From e9c78767dd87c003c6e93f679e531e34b90d04c7 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:55:42 +0530 Subject: [PATCH 013/612] [IMP] improved code bzr revid: tpa@tinyerp.com-20120712132542-c19ysod7jm5jmukc --- addons/web/controllers/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 75feed44c69..6c0e2e4dc9b 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -357,9 +357,7 @@ class WebClient(openerpweb.Controller): for mod in mods: messages[mod] = {"messages":[]} proxy = req.session.proxy("translation") - trans = proxy.load(req.session._db, [mod], langs, "web") - if trans: - messages[mod] = trans + messages[mod] = proxy.load(req.session._db, [mod], langs, "web") # keep loading from .po (Reason to run web without embedded mode) if not messages['web']['messages']: for addon_name in mods: From c17ea49de98e6cbe2ba2c760f3bc70323bfc9202 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:57:00 +0530 Subject: [PATCH 014/612] [IMP] improved code bzr revid: tpa@tinyerp.com-20120712132700-zc4co6o4plhzoi60 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 517b39e6999..e9b830302f7 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,7 +849,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web' and module_name == 'web': + if flag == 'web': transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): From f05ee5dfdb3dc5ec3f2db9b7685e5ed9e8e8fc01 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 11:23:30 +0530 Subject: [PATCH 015/612] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713055330-avz6ebzuqvcpxdd5 --- openerp/addons/base/module/module.py | 5 ++--- openerp/service/web_services.py | 4 +--- openerp/tools/translate.py | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 963fb292946..bbf3f3f5b64 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -594,9 +594,9 @@ class module(osv.osv): self.write(cr, uid, [mod_browse.id], {'category_id': p_id}) def update_translations(self, cr, uid, ids, filter_lang=None, context=None): + pool = pooler.get_pool(cr.dbname) if context is None: context = {} - pool = pooler.get_pool(cr.dbname) if not filter_lang: lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) @@ -607,8 +607,7 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - traslation_obj = pool.get('ir.translation') - traslation_obj.load(cr, [mod.name], filter_lang, context=context) + pool.get('ir.translation').load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 17935efda54..0cfcf468a2b 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -784,9 +784,7 @@ class translation(netsvc.ExportService): def exp_load(self, db, modules, langs, flag=None, context=None): cr = pooler.get_db(db).cursor() - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') - translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) + translated_data = pooler.get_pool(db).get('ir.translation').load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index e9b830302f7..bbada8c2efc 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -846,20 +846,18 @@ def trans_generate(lang, modules, cr): def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') + traslation_obj = pooler.get_pool(cr.dbname).get('ir.translation') _logger.info("loading %s", filename) + transl = [] if flag == 'web': - transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): transl.append({'id': trans.src, 'string': trans.value}) - return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return [] + return transl except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From 402ba23000ed38f2d4c95d5b240d6327d70b3731 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 12:25:21 +0530 Subject: [PATCH 016/612] [IMP] improved code to retun traslation in proper format from server bzr revid: tpa@tinyerp.com-20120713065521-07a7qdfxfio673cq --- openerp/addons/base/ir/ir_translation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 0a3124b36ce..cd6fa271852 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -325,8 +325,9 @@ class ir_translation(osv.osv): return ir_translation_import_cursor(cr, uid, self, context=context) def load(self, cr, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} + translated_data = {} for module_name in modules: + translated_data[module_name] = {'messages':[]} modpath = openerp.modules.get_module_path(module_name) if not modpath: # unable to find the module. we skip @@ -340,7 +341,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -350,7 +351,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data From 0d4bd736e1bd8c8acb78f63e190111b1c72b05af Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 12:30:48 +0530 Subject: [PATCH 017/612] [IMP] improved code to get formeted traslation from server. bzr revid: tpa@tinyerp.com-20120713070048-7yxm3fcajemiingc --- addons/web/controllers/main.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6c0e2e4dc9b..7cde4040e4f 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -353,11 +353,8 @@ class WebClient(openerpweb.Controller): langs = lang.split(separator) langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)] - messages = {} - for mod in mods: - messages[mod] = {"messages":[]} - proxy = req.session.proxy("translation") - messages[mod] = proxy.load(req.session._db, [mod], langs, "web") + proxy = req.session.proxy("translation") + messages = proxy.load(req.session._db, mods, langs, "web") # keep loading from .po (Reason to run web without embedded mode) if not messages['web']['messages']: for addon_name in mods: From 8383d6a2459588b332ecdcb0a26c38f92c5ab317 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 14:58:38 +0530 Subject: [PATCH 018/612] [IMP] Fetch only traslated and distinct strings using sql. bzr revid: tpa@tinyerp.com-20120713092838-5th251msbdkgjdnb --- openerp/tools/translate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index bbada8c2efc..11801326ba3 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,9 +850,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) - for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): - transl.append({'id': trans.src, 'string': trans.value}) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + for src, value in cr.fetchall(): + transl.append({'id': src, 'string': value}) else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) From 48a344c1e8d88b005eaf29128890196fd096b441 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 15:24:48 +0530 Subject: [PATCH 019/612] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713095448-ghr750h2jk9ivsj2 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 11801326ba3..25e80e260fa 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,7 +850,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND lang='%s' AND value != ''"% (module_name,lang)) for src, value in cr.fetchall(): transl.append({'id': src, 'string': value}) else: From 58e20e9c8f0f40b93a0d4dd1ff68666d49311949 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 11:30:56 +0530 Subject: [PATCH 020/612] [IMP] improved code to load data from po. bzr revid: tpa@tinyerp.com-20120716060056-3az6awpd6gw39hii --- addons/web/controllers/main.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 7cde4040e4f..024360ce5e6 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -355,14 +355,11 @@ class WebClient(openerpweb.Controller): proxy = req.session.proxy("translation") messages = proxy.load(req.session._db, mods, langs, "web") - # keep loading from .po (Reason to run web without embedded mode) - if not messages['web']['messages']: - for addon_name in mods: - transl = {'messages':[]} - messages[addon_name] = transl - addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] + for mod in messages: + if not messages[mod]['messages']: + addons_path = openerpweb.addons_manifest[mod]['addons_path'] for l in langs: - f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") + f_name = os.path.join(addons_path, mod, "i18n", l + ".po") if not os.path.exists(f_name): continue try: @@ -372,7 +369,7 @@ class WebClient(openerpweb.Controller): continue for x in po: if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) + messages[mod]["messages"].append({'id': x.id, 'string': x.string}) return {"modules": messages, "lang_parameters": lang_obj} From d931a099ac4551a4d24724a09ecc12d3951a82b6 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:04:58 +0530 Subject: [PATCH 021/612] [ADD] added test case for translation load in tests_xmlrpc.py. bzr revid: tpa@tinyerp.com-20120716103458-p2l9p38g4ubl7d2i --- openerp/tests/common.py | 1 + openerp/tests/test_xmlrpc.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index ef5b0586136..351645c41f2 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -72,6 +72,7 @@ class RpcCase(unittest2.TestCase): self.proxy.common_61 = xmlrpclib.ServerProxy(url_61 + 'common') self.proxy.db_61 = xmlrpclib.ServerProxy(url_61 + 'db') self.proxy.model_61 = xmlrpclib.ServerProxy(url_61 + 'model/' + DB) + self.proxy.translation_61 = xmlrpclib.ServerProxy(url_61 + 'translation') @classmethod def generate_database_name(cls): diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 37655e72718..5f73325fe4c 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -71,6 +71,11 @@ class test_xmlrpc(common.RpcCase): """ assert self.proxy.db_60.drop(ADMIN_PASSWORD, DB) is True + def test_xmlrpc_61_translation_load(self): + """ Try a load translation service like web. """ + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + assert messages + if __name__ == '__main__': unittest2.main() From 74fd43b82c211d416fef8f9b1ff10bc43d5aaab8 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:13:05 +0530 Subject: [PATCH 022/612] [IMP] change language. bzr revid: tpa@tinyerp.com-20120716104305-ws8igxbfx7m0bwy9 --- openerp/tests/test_xmlrpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 5f73325fe4c..70ac6b1f75f 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -73,7 +73,7 @@ class test_xmlrpc(common.RpcCase): def test_xmlrpc_61_translation_load(self): """ Try a load translation service like web. """ - messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['en_US'], 'web') assert messages if __name__ == '__main__': From 79b29e17c4966f0be4f6bc42397c156e6e2d7e49 Mon Sep 17 00:00:00 2001 From: "pankita shah (Open ERP)" Date: Wed, 25 Jul 2012 12:59:52 +0530 Subject: [PATCH 023/612] [FIX]remove ProgrammingError in event module bzr revid: shp@tinyerp.com-20120725072952-mcnyappum33w1smy --- addons/event/report/report_event_registration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py index 17472e0cc95..59515f87a00 100644 --- a/addons/event/report/report_event_registration.py +++ b/addons/event/report/report_event_registration.py @@ -80,6 +80,7 @@ class report_event_registration(osv.osv): LEFT JOIN event_registration r ON (e.id=r.event_id) + where r.id is not null GROUP BY event_id, From 7096a336c084bab9f12aa1d13ae96e82cbf12d7d Mon Sep 17 00:00:00 2001 From: Date: Tue, 28 Aug 2012 16:22:02 +0200 Subject: [PATCH 024/612] [FIX] a default value (created using "Set Default" wizard) should never be shared between companies, but assigned on the user's company bzr revid: guewen.baconnier@camptocamp.com-20120828142202-9lwdicrdgc2spp6s --- addons/web/static/src/js/view_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index b64f34f3aaf..60e3d8361bc 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1007,7 +1007,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM field_to_set, self.fields[field_to_set].get_value(), all_users, - false, + true, condition || false ]).then(function () { d.close(); }); }} From ca9c79727541fbf87f316906887e920e79b9550c Mon Sep 17 00:00:00 2001 From: Amit Parik Date: Wed, 5 Sep 2012 17:03:13 +0530 Subject: [PATCH 025/612] [FIX]:project_timesheet impossible to edit task work bzr revid: pja@tinyerp.com-20120905113313-c2cbi37xqr6mnvrc --- addons/project_timesheet/project_timesheet.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py index 1e50848201c..12d1eedbeb2 100644 --- a/addons/project_timesheet/project_timesheet.py +++ b/addons/project_timesheet/project_timesheet.py @@ -166,10 +166,7 @@ class project_work(osv.osv): vals_line['name'] = '%s: %s' % (tools.ustr(task.task_id.name), tools.ustr(vals['name']) or '/') if 'user_id' in vals: vals_line['user_id'] = vals['user_id'] - result = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id)) - for fld in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'): - if result.get(fld, False): - vals_line[fld] = result[fld] + if 'date' in vals: vals_line['date'] = vals['date'][:10] @@ -177,7 +174,10 @@ class project_work(osv.osv): default_uom = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id vals_line['unit_amount'] = vals['hours'] prod_id = vals_line.get('product_id', line_id.product_id.id) # False may be set - + result = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id)) + for fld in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'): + if result.get(fld, False): + vals_line[fld] = result[fld] if result.get('product_uom_id',False) and (not result['product_uom_id'] == default_uom): vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, default_uom, vals['hours'], result['product_uom_id']) From 09ba29883c06d1f1de06c40e89c864c85f53d5c7 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 11 Sep 2012 15:52:54 +0200 Subject: [PATCH 026/612] [FIX] ir.translation: typo in last sync with trunk bzr revid: odo@openerp.com-20120911135254-uqi1s4n8qh0e3d1y --- openerp/addons/base/ir/ir_translation.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 68b413344b2..c8f9cf8e6fe 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -68,7 +68,6 @@ class ir_translation_import_cursor(object): # Note that Postgres will NOT inherit the constraints or indexes # of ir_translation, so this copy will be much faster. - cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), imd_name VARCHAR(128) @@ -77,16 +76,14 @@ class ir_translation_import_cursor(object): def push(self, trans_dict): """Feed a translation, as a dictionary, into the cursor """ - params = dict(trans_dict, - state="translated" if trans_dict['value'] else "to_translate") + params = dict(trans_dict, state="translated" if trans_dict['value'] else "to_translate") self._cr.execute("""INSERT INTO %s (name, lang, res_id, src, type, imd_model, module, imd_name, value, state) - VALUES (%(name)s, %(lang)s, %(res_id)s, %(src)s, %(type)s, %(imd_model)s, %(module)s, %(imd_name)s, %(value)s, %(state)s)""", - params) + VALUES (%%(name)s, %%(lang)s, %%(res_id)s, %%(src)s, %%(type)s, %%(imd_model)s, %%(module)s, %%(imd_name)s, %%(value)s, %%(state)s)""" % self._table_name, + params) def finish(self): """ Transfer the data from the temp table to ir.translation """ - cr = self._cr if self._debug: cr.execute("SELECT count(*) FROM %s" % self._table_name) @@ -129,7 +126,6 @@ class ir_translation_import_cursor(object): """ % (self._parent_table, self._table_name, find_expr)) # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module, state) SELECT name, lang, res_id, src, type, value, module, state FROM %s AS ti From 550751b35825d60af0ed5985cd46b4ff4e2d3d01 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 13 Sep 2012 16:29:20 +0200 Subject: [PATCH 027/612] [IMP] translations: wip, remove unnecessary code, support loading PO comments and storing them, split ir.translation view data in separate XML file bzr revid: odo@openerp.com-20120913142920-ggpeqth4s2wwqwd2 --- openerp/addons/base/__openerp__.py | 1 + openerp/addons/base/ir/ir.xml | 69 ------------- openerp/addons/base/ir/ir_translation.py | 123 ++++++++++++----------- openerp/addons/base/ir/ir_ui_view.py | 5 +- openerp/addons/base/module/module.py | 16 +-- openerp/service/web_services.py | 24 ----- openerp/tests/common.py | 1 - openerp/tests/test_xmlrpc.py | 5 - openerp/tools/translate.py | 61 ++++++----- 9 files changed, 98 insertions(+), 207 deletions(-) diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 937c9cbd20b..082cf260373 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -44,6 +44,7 @@ The kernel of OpenERP, needed for all installation. 'data/res.country.state.csv', 'ir/wizard/wizard_menu_view.xml', 'ir/ir.xml', + 'ir/ir_translation_view.xml', 'ir/ir_filters.xml', 'ir/ir_config_parameter_view.xml', 'ir/workflow/workflow_view.xml', diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index 29bb681981a..515d9641001 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -1147,75 +1147,6 @@ - - - - Translations - ir.translation - - - - - - - - - - - - - Translations - ir.translation - -
-
- -
- - - - - - - - - - - - - - - - - - -
-
-
- - Translations - ir.translation - - - - - - - - - - - - - Translated Terms - ir.translation - form - - - - + - - -
  • - -
  • + + + + + + + +
  • Username
  • +
    + + + +
    -
    - - -
    -
    - Name =
    - Email =
    - Password =
    - Confirmation =
    - -
    -
    -
    - -
    From 597919467d4ecedddb2b3e14798c10bdf020f7ea Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 14:45:57 +0200 Subject: [PATCH 048/612] [IMP] auth_signup: add css bzr revid: rco@openerp.com-20120925124557-2yka4yu0x7528atl --- addons/auth_signup/__openerp__.py | 1 + addons/auth_signup/static/src/css/Makefile | 3 +++ addons/auth_signup/static/src/css/base.css | 4 ++++ addons/auth_signup/static/src/css/base.sass | 7 +++++++ 4 files changed, 15 insertions(+) create mode 100644 addons/auth_signup/static/src/css/Makefile create mode 100644 addons/auth_signup/static/src/css/base.css create mode 100644 addons/auth_signup/static/src/css/base.sass diff --git a/addons/auth_signup/__openerp__.py b/addons/auth_signup/__openerp__.py index 9cfe89cdc1c..5bb3aab4ec0 100644 --- a/addons/auth_signup/__openerp__.py +++ b/addons/auth_signup/__openerp__.py @@ -36,5 +36,6 @@ Allow users to sign up. 'res_config.xml', ], 'js': ['static/src/js/auth_signup.js'], + 'css' : ['static/src/css/base.css'], 'qweb': ['static/src/xml/auth_signup.xml'], } diff --git a/addons/auth_signup/static/src/css/Makefile b/addons/auth_signup/static/src/css/Makefile new file mode 100644 index 00000000000..d6b4f4b2fc8 --- /dev/null +++ b/addons/auth_signup/static/src/css/Makefile @@ -0,0 +1,3 @@ +base.css: base.sass + sass --trace -t expanded base.sass base.css + diff --git a/addons/auth_signup/static/src/css/base.css b/addons/auth_signup/static/src/css/base.css new file mode 100644 index 00000000000..153f27bd129 --- /dev/null +++ b/addons/auth_signup/static/src/css/base.css @@ -0,0 +1,4 @@ +@charset "utf-8"; +.openerp .oe_login input[type="checkbox"] { + width: 21px !important; +} diff --git a/addons/auth_signup/static/src/css/base.sass b/addons/auth_signup/static/src/css/base.sass new file mode 100644 index 00000000000..87bdb623727 --- /dev/null +++ b/addons/auth_signup/static/src/css/base.sass @@ -0,0 +1,7 @@ +@charset "utf-8" + +.openerp + // Login form + .oe_login + input[type="checkbox"] + width: 21px !important From e184913f346f891fd74c2c6f1e0f048beb283fbb Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 14:55:22 +0200 Subject: [PATCH 049/612] [FIX] auth_signup: store and retrieve config parameters that may be null bzr revid: rco@openerp.com-20120925125522-2t74fta15yfoesc1 --- addons/auth_signup/res_config.py | 11 +++++++---- addons/auth_signup/res_users.py | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/addons/auth_signup/res_config.py b/addons/auth_signup/res_config.py index 36732d439f5..c69c01127f6 100644 --- a/addons/auth_signup/res_config.py +++ b/addons/auth_signup/res_config.py @@ -20,6 +20,7 @@ ############################################################################## from openerp.osv import osv, fields +from openerp.tools.safe_eval import safe_eval class base_config_settings(osv.TransientModel): _inherit = 'base.config.settings' @@ -31,13 +32,15 @@ class base_config_settings(osv.TransientModel): def get_default_auth_signup_template_user_id(self, cr, uid, fields, context=None): icp = self.pool.get('ir.config_parameter') + # we use safe_eval on the result, since the value of the parameter is a nonempty string return { - 'auth_signup_uninvited': icp.get_param(cr, uid, 'auth_signup.allow_uninvited', False), - 'auth_signup_template_user_id': icp.get_param(cr, uid, 'auth_signup.template_user_id', False), + 'auth_signup_uninvited': safe_eval(icp.get_param(cr, uid, 'auth_signup.allow_uninvited', 'False')), + 'auth_signup_template_user_id': safe_eval(icp.get_param(cr, uid, 'auth_signup.template_user_id', 'False')), } def set_auth_signup_template_user_id(self, cr, uid, ids, context=None): config = self.browse(cr, uid, ids[0], context=context) icp = self.pool.get('ir.config_parameter') - icp.set_param(cr, uid, 'auth_signup.allow_uninvited', config.auth_signup_uninvited) - icp.set_param(cr, uid, 'auth_signup.template_user_id', config.auth_signup_template_user_id.id) + # we store the repr of the values, since the value of the parameter is a required string + icp.set_param(cr, uid, 'auth_signup.allow_uninvited', repr(config.auth_signup_uninvited)) + icp.set_param(cr, uid, 'auth_signup.template_user_id', repr(config.auth_signup_template_user_id.id)) diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py index 600ed9c000e..6956c8e2109 100644 --- a/addons/auth_signup/res_users.py +++ b/addons/auth_signup/res_users.py @@ -23,6 +23,7 @@ import openerp from openerp.osv import osv, fields from openerp import SUPERUSER_ID from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT +from openerp.tools.safe_eval import safe_eval import time import random @@ -152,10 +153,11 @@ class res_users(osv.Model): """ create a new user from the template user """ # check that uninvited users may sign up ir_config_parameter = self.pool.get('ir.config_parameter') - if token and not ir_config_parameter.get_param(cr, uid, 'auth_signup.allow_uninvited', False): - raise Exception('Signup is not allowed for uninvited users') + if not token: + if not safe_eval(ir_config_parameter.get_param(cr, uid, 'auth_signup.allow_uninvited', 'False')): + raise Exception('Signup is not allowed for uninvited users') - template_user_id = ir_config_parameter.get_param(cr, uid, 'auth_signup.template_user_id') + template_user_id = safe_eval(ir_config_parameter.get_param(cr, uid, 'auth_signup.template_user_id', 'False')) assert template_user_id, 'Signup: missing template user' values.update({'active': True, 'signup_token': False, 'signup_expiration': False}) return self.copy(cr, uid, template_user_id, values, context=context) From d5c69fa87e9d17c92c00347af73fce53fb47dcd4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 15:59:55 +0200 Subject: [PATCH 050/612] [FIX] use lists instead of iterators in BaseModel._extract_records * although it does use an explicit external index, it turns out the code is less complex * the rewrapping of (many) iterators on top of one another ended up blowing Python's stack during ``next`` calls, which Python does *not* like * added a 900-ish import test file to check for these things bzr revid: xmo@openerp.com-20120925135955-oielhopegnefyctm --- openerp/addons/base/ir/ir_fields.py | 5 +- openerp/osv/orm.py | 53 +++++-------------- .../addons/test_impex/tests/test_load.py | 13 +++++ 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index cec74e8976e..03d95fc67a6 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -69,7 +69,7 @@ class ir_fields_converter(orm.Model): """ # FIXME: return None converter = getattr( - self, '_%s_to_%s' % (fromtype.__name__, column._type)) + self, '_%s_to_%s' % (fromtype.__name__, column._type), None) if not converter: return None return functools.partial( @@ -113,6 +113,9 @@ class ir_fields_converter(orm.Model): def _str_to_text(self, cr, uid, model, column, value, context=None): return value or False + def _str_to_binary(self, cr, uid, model, column, value, context=None): + return value or False + def _get_translations(self, cr, uid, types, src, context): types = tuple(types) # Cache translations so they don't have to be reloaded from scratch on diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 25974760bdd..eb7745b2f6e 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1527,7 +1527,7 @@ class BaseModel(object): return {'ids': ids, 'messages': messages} def _extract_records(self, cr, uid, fields_, data, context=None, log=lambda a: None): - """ Generates record dicts from the data iterable. + """ Generates record dicts from the data sequence. The result is a generator of dicts mapping field names to raw (unconverted, unvalidated) values. @@ -1562,12 +1562,11 @@ class BaseModel(object): def only_o2m_values(row, f=get_nono2m_values, g=get_o2m_values): return any(g(row)) and not any(f(row)) - rows = CountingStream(data) + index = 0 while True: - row = next(rows, None) - if row is None: return - record_row_index = rows.index + if index >= len(data): return + row = data[index] # copy non-relational fields to record dict record = dict((field[0], value) for field, value in itertools.izip(fields_, row) @@ -1575,10 +1574,10 @@ class BaseModel(object): # Get all following rows which have relational values attached to # the current record (no non-relational values) - # WARNING: replaces existing ``rows`` - record_span, _rows = span(only_o2m_values, rows) + record_span = itertools.takewhile( + only_o2m_values, itertools.islice(data, index + 1, None)) # stitch record row back on for relational fields - record_span = itertools.chain([row], record_span) + record_span = list(itertools.chain([row], record_span)) for relfield in set( field[0] for field in fields_ if is_relational(field[0])): @@ -1586,8 +1585,6 @@ class BaseModel(object): # FIXME: how to not use _obj without relying on fields_get? Model = self.pool[column._obj] - # copy stream to reuse for next relational field - fieldrows, record_span = itertools.tee(record_span) # get only cells for this sub-field, should be strictly # non-empty, field path [None] is for name_get column indices, subfields = zip(*((index, field[1:] or [None]) @@ -1596,26 +1593,17 @@ class BaseModel(object): # return all rows which have at least one value for the # subfields of relfield - relfield_data = filter(any, map(itemgetter_tuple(indices), fieldrows)) + relfield_data = filter(any, map(itemgetter_tuple(indices), record_span)) record[relfield] = [subrecord for subrecord, _subinfo in Model._extract_records( cr, uid, subfields, relfield_data, context=context, log=log)] - # Ensure full consumption of the span (and therefore advancement of - # ``rows``) even if there are no relational fields. Needs two as - # the code above stiched the row back on (so first call may only - # get the stiched row without advancing the underlying operator row - # itself) - next(record_span, None) - next(record_span, None) - # old rows consumption (by iterating the span) should be done here, - # at this point the old ``rows`` is 1 past `span` (either on the - # next record row or past ``StopIteration``, so wrap new ``rows`` - # (``_rows``) in a counting stream indexed 1-before the old - # ``rows`` - rows = CountingStream(_rows, rows.index - 1) - yield record, {'rows': {'from': record_row_index,'to': rows.index}} + yield record, {'rows': { + 'from': index, + 'to': index + len(record_span) - 1 + }} + index += len(record_span) def _convert_records(self, cr, uid, records, context=None, log=lambda a: None): """ Converts records from the source iterable (recursive dicts of @@ -5369,21 +5357,6 @@ class AbstractModel(BaseModel): _auto = False # don't create any database backend for AbstractModels _register = False # not visible in ORM registry, meant to be python-inherited only -def span(predicate, iterable): - """ Splits the iterable between the longest prefix of ``iterable`` whose - elements satisfy ``predicate`` and the rest. - - If called with a list, equivalent to:: - - takewhile(predicate, lst), dropwhile(predicate, lst) - - :param callable predicate: - :param iterable: - :rtype: (iterable, iterable) - """ - it1, it2 = itertools.tee(iterable) - return (itertools.takewhile(predicate, it1), - itertools.dropwhile(predicate, it2)) def itemgetter_tuple(items): """ Fixes itemgetter inconsistency (useful in some cases) of not returning a tuple if len(items) == 1: always returns an n-tuple where n = len(items) diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index eb777a57988..72442963af5 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +import json +import pkgutil + import openerp.modules.registry import openerp @@ -956,5 +959,15 @@ class test_o2m_multiple(ImporterCase): self.assertEqual(values(b.child1), [11, 12, 13, 14]) self.assertEqual(values(b.child2), [21, 22, 23]) +class test_realworld(common.TransactionCase): + def test_bigfile(self): + data = json.loads(pkgutil.get_data(self.__module__, 'contacts_big.json')) + result = self.registry('res.partner').load( + self.cr, openerp.SUPERUSER_ID, + ['name', 'mobile', 'email', 'image'], + data) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), len(data)) + # function, related, reference: written to db as-is... # => function uses @type for value coercion/conversion From 9906a2bda10ca089fff55521f3252f4f8b178344 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 16:34:33 +0200 Subject: [PATCH 051/612] [IMP] auth_signup: improve error message handling in web client bzr revid: rco@openerp.com-20120925143433-p4r2gl6t37dw0s17 --- addons/auth_signup/controllers/main.py | 8 +-- .../auth_signup/static/src/js/auth_signup.js | 61 ++++++++++++++----- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 343c660ff7d..6e053715c09 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -55,14 +55,10 @@ class Controller(openerpweb.Controller): credentials = res_users.signup(cr, SUPERUSER_ID, values, token) cr.commit() return login_and_redirect(req, *credentials) - except AttributeError: - # auth_signup is not installed - _logger.exception('attribute error when signup') - url = "/#action=auth_signup&error=NA" # Not Available - except Exception: + except Exception as e: # signup error _logger.exception('error when signup') - url = "/#action=auth_signup&error=UE" # Unexcpected Error + url = "/#action=login&error_message=%s" % werkzeug.urls.url_quote(e.message) return werkzeug.utils.redirect(url) # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js index bec32ce2803..9c90358d9e3 100644 --- a/addons/auth_signup/static/src/js/auth_signup.js +++ b/addons/auth_signup/static/src/js/auth_signup.js @@ -6,9 +6,21 @@ openerp.auth_signup = function(instance) { start: function() { var self = this; var d = this._super(); + // hide the signup fields in the case of a regular login self.on_change_mode() self.$("form input[name=signup]").click(self.on_change_mode); + + // if there is an error message, show it then forget it + if (self.params.error_message) { + this.$el.addClass('oe_login_invalid'); + this.$(".oe_login_error_message").text(self.params.error_message); + delete self.params.error_message; + } else { + this.$el.removeClass('oe_login_invalid'); + this.$(".oe_login_error_message").text("Invalid username or password"); + } + // in case of a signup, retrieve the user information from the token if (self.params.db && self.params.token) { d = self.rpc("/auth_signup/retrieve", {dbname: self.params.db, token: self.params.token}) @@ -28,8 +40,14 @@ openerp.auth_signup = function(instance) { this.$("form input[name=confirm_password]").val(""); this.on_change_mode(); }, - on_token_failed: function(result) { - // currently does nothing + on_token_failed: function(result, ev) { + if (ev) { + ev.preventDefault(); + } + this.$el.addClass('oe_login_invalid'); + this.$(".oe_login_error_message").text("Invalid signup token"); + delete this.params.db; + delete this.params.token; }, on_change_mode: function() { // 'mode' has changed: regular login, sign up, reset password @@ -43,25 +61,36 @@ openerp.auth_signup = function(instance) { } if (this.params.token || this.$("input[name=signup]:checked").val()) { // signup user (or reset password) - var db = this.params.db; + var db = this.$("form [name=db]").val(); var name = this.$("form input[name=name]").val(); var login = this.$("form input[name=login]").val(); var password = this.$("form input[name=password]").val(); var confirm_password = this.$("form input[name=confirm_password]").val(); - - if (password && password === confirm_password) { - var params = { - dbname : db, - token: this.params.token, - name: name, - login: login, - password: password, - }; - var url = "/auth_signup/signup?" + $.param(params); - window.location = url; - } else { - alert('Incorrect password; please retype your password.'); + if (!db) { + this.do_warn("Login", "No database selected !"); + return false; + } else if (!name) { + this.do_warn("Login", "Please enter a name.") + return false; + } else if (!login) { + this.do_warn("Login", "Please enter a username.") + return false; + } else if (!password || !confirm_password) { + this.do_warn("Login", "Please enter a password and confirm it.") + return false; + } else if (password !== confirm_password) { + this.do_warn("Login", "Passwords do not match; please retype them.") + return false; } + var params = { + dbname : db, + token: this.params.token || "", + name: name, + login: login, + password: password, + }; + var url = "/auth_signup/signup?" + $.param(params); + window.location = url; } else { // regular login this._super(ev); From e61dc509341ed2cd1222869048a81b2db209e21d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 17:59:15 +0200 Subject: [PATCH 052/612] [IMP] convert empty import fields to False values without going through converters simplifies the converter methods by avoiding redundant emptiness checks bzr revid: xmo@openerp.com-20120925155915-82p2s6stpww37p5n --- openerp/addons/base/ir/ir_fields.py | 8 +++----- openerp/osv/orm.py | 4 +++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 03d95fc67a6..621dd93d469 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -100,21 +100,19 @@ class ir_fields_converter(orm.Model): return True def _str_to_integer(self, cr, uid, model, column, value, context=None): - if not value: return False return int(value) def _str_to_float(self, cr, uid, model, column, value, context=None): - if not value: return False return float(value) def _str_to_char(self, cr, uid, model, column, value, context=None): - return value or False + return value def _str_to_text(self, cr, uid, model, column, value, context=None): - return value or False + return value def _str_to_binary(self, cr, uid, model, column, value, context=None): - return value or False + return value def _get_translations(self, cr, uid, types, src, context): types = tuple(types) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index eb7745b2f6e..81063deb180 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -68,7 +68,6 @@ from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ from openerp import SUPERUSER_ID from query import Query -from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) _schema = logging.getLogger(__name__ + '.schema') @@ -1662,6 +1661,9 @@ class BaseModel(object): for field, strvalue in record.iteritems(): if field in (None, 'id', '.id'): continue + if not strvalue: + converted[field] = False + continue # In warnings and error messages, use translated string as # field name From dad2475d9f68d8bafb0dcb633a7b05256a8ea0be Mon Sep 17 00:00:00 2001 From: Saurang Suthar Date: Wed, 26 Sep 2012 12:01:47 +0530 Subject: [PATCH 053/612] [IMP]sale_crm:made Convert to Quotation button invisible if opportunity is closed(Won) bzr revid: ssu@tinyerp.com-20120926063147-l4nvifaehms9lugc --- addons/sale_crm/sale_crm_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index e54ba158b9b..efee3953788 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -9,8 +9,8 @@ - -
  • - +
  • Reset password
  • + From 5763e40506f9f155e09b2fccbc7ffa4247b02b9b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 17:14:21 +0200 Subject: [PATCH 162/612] [IMP] orm: remove trailing spaces bzr revid: chs@openerp.com-20121001151421-vdfkzuf864rz8q20 --- openerp/osv/orm.py | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 47afda39e5e..8b78621db03 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -372,7 +372,7 @@ class browse_record(object): else: return attr else: - error_msg = "Field '%s' does not exist in object '%s'" % (name, self) + error_msg = "Field '%s' does not exist in object '%s'" % (name, self) self.__logger.warning(error_msg) if self.__logger.isEnabledFor(logging.DEBUG): self.__logger.debug(''.join(traceback.format_stack())) @@ -712,7 +712,7 @@ class BaseModel(object): def log(self, cr, uid, id, message, secondary=False, context=None): return _logger.warning("log() is deprecated. Please use OpenChatter notification system instead of the res.log mechanism.") - + def view_init(self, cr, uid, fields_list, context=None): """Override this method to do specific things when a view on the object is opened.""" pass @@ -902,7 +902,7 @@ class BaseModel(object): # If new class defines a constraint with # same function name, we let it override # the old one. - + new[c2] = c exist = True break @@ -1596,7 +1596,7 @@ class BaseModel(object): def user_has_groups(self, cr, uid, groups, context=None): """Return true if the user is at least member of one of the groups in groups_str. Typically used to resolve ``groups`` attribute - in view and model definitions. + in view and model definitions. :param str groups: comma-separated list of fully-qualified group external IDs, e.g.: ``base.group_user,base.group_system`` @@ -1639,7 +1639,7 @@ class BaseModel(object): the field should be completely removed from the view, as it is completely unavailable for non-members - :return: True if field should be included in the result of fields_view_get + :return: True if field should be included in the result of fields_view_get """ if node.tag == 'field' and node.get('name') in self._all_columns: column = self._all_columns[node.get('name')].column @@ -1914,7 +1914,7 @@ class BaseModel(object): def _get_default_calendar_view(self, cr, user, context=None): """ Generates a default calendar view by trying to infer calendar fields from a number of pre-set attribute names - + :param cr: database cursor :param int user: user id :param dict context: connection context @@ -1993,7 +1993,7 @@ class BaseModel(object): def raise_view_error(error_msg, child_view_id): view, child_view = self.pool.get('ir.ui.view').browse(cr, user, [view_id, child_view_id], context) - error_msg = error_msg % {'parent_xml_id': view.xml_id} + error_msg = error_msg % {'parent_xml_id': view.xml_id} raise AttributeError("View definition error for inherited view '%s' on model '%s': %s" % (child_view.xml_id, self._name, error_msg)) @@ -2029,7 +2029,7 @@ class BaseModel(object): if all(node.get(attr) == spec.get(attr) \ for attr in spec.attrib if attr not in ('position','version')): - # Version spec should match parent's root element's version + # Version spec should match parent's root element's version if spec.get('version') and spec.get('version') != source.get('version'): return None return node @@ -2103,7 +2103,7 @@ class BaseModel(object): raise_view_error("Mismatching view API version for element '%s': %r vs %r in parent view '%%(parent_xml_id)s'" % \ (tag, spec.get('version'), source.get('version')), inherit_id) raise_view_error("Element '%s' not found in parent view '%%(parent_xml_id)s'" % tag, inherit_id) - + return source def apply_view_inheritance(cr, user, source, inherit_id): @@ -2318,7 +2318,7 @@ class BaseModel(object): or ``'='``. :param int limit: optional max number of records to return :rtype: list - :return: list of pairs ``(id,text_repr)`` for all matching records. + :return: list of pairs ``(id,text_repr)`` for all matching records. """ return self._name_search(cr, user, name, args, operator, context, limit) @@ -2448,7 +2448,7 @@ class BaseModel(object): # This is useful to implement kanban views for instance, where all columns # should be displayed even if they don't contain any record. - # Grab the list of all groups that should be displayed, including all present groups + # Grab the list of all groups that should be displayed, including all present groups present_group_ids = [x[groupby][0] for x in read_group_result if x[groupby]] all_groups,folded = self._group_by_full[groupby](self, cr, uid, present_group_ids, domain, read_group_order=read_group_order, @@ -2824,28 +2824,28 @@ class BaseModel(object): def _m2o_fix_foreign_key(self, cr, source_table, source_field, dest_model, ondelete): # Find FK constraint(s) currently established for the m2o field, - # and see whether they are stale or not + # and see whether they are stale or not cr.execute("""SELECT confdeltype as ondelete_rule, conname as constraint_name, cl2.relname as foreign_table FROM pg_constraint as con, pg_class as cl1, pg_class as cl2, pg_attribute as att1, pg_attribute as att2 - WHERE con.conrelid = cl1.oid - AND cl1.relname = %s - AND con.confrelid = cl2.oid - AND array_lower(con.conkey, 1) = 1 - AND con.conkey[1] = att1.attnum - AND att1.attrelid = cl1.oid - AND att1.attname = %s - AND array_lower(con.confkey, 1) = 1 - AND con.confkey[1] = att2.attnum - AND att2.attrelid = cl2.oid - AND att2.attname = %s + WHERE con.conrelid = cl1.oid + AND cl1.relname = %s + AND con.confrelid = cl2.oid + AND array_lower(con.conkey, 1) = 1 + AND con.conkey[1] = att1.attnum + AND att1.attrelid = cl1.oid + AND att1.attname = %s + AND array_lower(con.confkey, 1) = 1 + AND con.confkey[1] = att2.attnum + AND att2.attrelid = cl2.oid + AND att2.attname = %s AND con.contype = 'f'""", (source_table, source_field, 'id')) constraints = cr.dictfetchall() if constraints: if len(constraints) == 1: # Is it the right constraint? - cons, = constraints + cons, = constraints if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\ or cons['foreign_table'] != dest_model._table: _schema.debug("Table '%s': dropping obsolete FK constraint: '%s'", @@ -3218,7 +3218,7 @@ class BaseModel(object): def _o2m_raise_on_missing_reference(self, cr, f): # TODO this check should be a method on fields.one2many. - + other = self.pool.get(f._obj) if other: # TODO the condition could use fields_get_keys(). @@ -3735,7 +3735,7 @@ class BaseModel(object): the length of `ids`, and raise an appropriate exception if it does not. """ if cr.rowcount != len(ids): - # Attempt to distinguish record rule restriction vs deleted records, + # Attempt to distinguish record rule restriction vs deleted records, # to provide a more specific error message cr.execute('SELECT id FROM ' + self._table + ' WHERE id IN %s', (tuple(ids),)) if cr.rowcount != len(ids): @@ -3790,13 +3790,13 @@ class BaseModel(object): self._check_record_rules_result_count(cr, uid, sub_ids, operation, context=context) def _workflow_trigger(self, cr, uid, ids, trigger, context=None): - """Call given workflow trigger as a result of a CRUD operation""" + """Call given workflow trigger as a result of a CRUD operation""" wf_service = netsvc.LocalService("workflow") for res_id in ids: getattr(wf_service, trigger)(uid, self._name, res_id, cr) def _workflow_signal(self, cr, uid, ids, signal, context=None): - """Send given workflow signal""" + """Send given workflow signal""" wf_service = netsvc.LocalService("workflow") for res_id in ids: wf_service.trg_validate(uid, self._name, res_id, signal, cr) @@ -3827,7 +3827,7 @@ class BaseModel(object): self.check_access_rights(cr, uid, 'unlink') ir_property = self.pool.get('ir.property') - + # Check if the records are used as default properties. domain = [('res_id', '=', False), ('value_reference', 'in', ['%s,%s' % (self._name, i) for i in ids]), @@ -4955,7 +4955,7 @@ class BaseModel(object): :return: map of ids to their fully qualified XML ID, defaulting to an empty string when there's none - (to be usable as a function field), + (to be usable as a function field), e.g.:: { 'id': 'module.ext_id', From 9d8ea41d450f738afe77c47b1f86c212e3132e33 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Mon, 1 Oct 2012 17:19:17 +0200 Subject: [PATCH 163/612] wip bzr revid: nicolas.vanhoren@openerp.com-20121001151917-o095dj2m8aypm3da --- addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml | 1 - addons/hr_timesheet_sheet/static/src/js/timesheet.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml index 6ff3e5c43e0..78fc997d15e 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml @@ -73,7 +73,6 @@ - This is a test. diff --git a/addons/hr_timesheet_sheet/static/src/js/timesheet.js b/addons/hr_timesheet_sheet/static/src/js/timesheet.js index 1cde7a80a90..9b186443217 100644 --- a/addons/hr_timesheet_sheet/static/src/js/timesheet.js +++ b/addons/hr_timesheet_sheet/static/src/js/timesheet.js @@ -21,7 +21,7 @@ openerp.hr_timesheet_sheet = function(instance) { this.on("change:sheets", this, this.update_sheets); this.res_o2m_drop = new instance.web.DropMisordered(); this.render_drop = new instance.web.DropMisordered(); - this.description_line = _t("No description"); + this.description_line = _t("/"); }, query_sheets: function() { var self = this; From b7e5519b4c0b4c212ef1268a09dacdfb26b704d8 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 17:37:53 +0200 Subject: [PATCH 164/612] [FIX] orm: handle fields.char() with not size correctly bzr revid: chs@openerp.com-20121001153753-um68vpz1caojm17r --- openerp/osv/orm.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 8b78621db03..ec995c6a8cc 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2967,14 +2967,14 @@ class BaseModel(object): ('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]), ('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]), ] - if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size: + if f_pg_type == 'varchar' and f._type == 'char' and ((f.size is None and f_pg_size) or f_pg_size < f.size): cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, pg_varchar(f.size))) cr.execute('UPDATE "%s" SET "%s"=temp_change_size::%s' % (self._table, k, pg_varchar(f.size))) cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,)) cr.commit() _schema.debug("Table '%s': column '%s' (type varchar) changed size from %s to %s", - self._table, k, f_pg_size, f.size) + self._table, k, f_pg_size or 'unlimited', f.size or 'unlimited') for c in casts: if (f_pg_type==c[0]) and (f._type==c[1]): if f_pg_type != f_obj_type: @@ -3207,8 +3207,7 @@ class BaseModel(object): # attlen is the number of bytes necessary to represent the type when # the type has a fixed size. If the type has a varying size attlen is # -1 and atttypmod is the size limit + 4, or -1 if there is no limit. - # Thus the query can return a negative size for a unlimited varchar. - cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \ + cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN (CASE WHEN a.atttypmod=-1 THEN 0 ELSE a.atttypmod-4 END) ELSE a.attlen END as size " \ "FROM pg_class c,pg_attribute a,pg_type t " \ "WHERE c.relname=%s " \ "AND c.oid=a.attrelid " \ From 7812c73354d9ca924c109b3c6331bfbe1986f388 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 1 Oct 2012 17:38:06 +0200 Subject: [PATCH 165/612] [IMP] yaml processing: improved previous patch by replacing the old parameter view with the result of fields_view_get() directly, to avoid having an extra parameter a bit useless bzr revid: qdp-launchpad@openerp.com-20121001153806-k40ly5vdzh1v3hv3 --- openerp/tools/yaml_import.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index f88f253c0f2..a5de5873908 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -313,14 +313,13 @@ class YamlInterpreter(object): #context = self.get_context(record, self.eval_context) #TOFIX: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module context = record.context - fields_view_get_result = False + view_info = False if view_id: varg = view_id if view_id is True: varg = False - fields_view_get_result = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) - view_id = etree.fromstring(fields_view_get_result['arch'].encode('utf-8')) + view_info = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) - record_dict = self._create_record(model, fields, view_id, default=default, fields_view_get=fields_view_get_result) + record_dict = self._create_record(model, fields, view_info, default=default) _logger.debug("RECORD_DICT %s" % record_dict) id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \ self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context) @@ -328,7 +327,8 @@ class YamlInterpreter(object): if config.get('import_partial'): self.cr.commit() - def _create_record(self, model, fields, view=False, parent={}, default=True, fields_view_get=None): + def _create_record(self, model, fields, view_info=False, parent={}, default=True): + view = view_info and etree.fromstring(view_info['arch'].encode('utf-8')) or False if view is not False: defaults = default and model._add_missing_default_values(self.cr, SUPERUSER_ID, {}, context=self.context) or {} fg = model.fields_get(self.cr, SUPERUSER_ID, context=self.context) @@ -357,17 +357,15 @@ class YamlInterpreter(object): field_name = el.attrib['name'] assert field_name in fg, "The field '%s' is defined in the form view but not on the object '%s'!" % (field_name, model._name) if field_name in fields: - view2 = None + one2many_form_view = None # if the form view is not inline, we call fields_view_get if (view is not False) and (fg[field_name]['type']=='one2many'): - tmp = fields_view_get['fields'][field_name]['views'] - if tmp.has_key('form'): - view2 = tmp.get('form') - if not view2: - view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - view2 = etree.fromstring(view2['arch'].encode('utf-8')) + one2many_form_view = view_info['fields'][field_name]['views'].get('form') + if not one2many_form_view: + one2many_form_view = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict, default=default, fields_view_get=fields_view_get) + view_info = one2many_form_view or view_info + field_value = self._eval_field(model, field_name, fields[field_name], view_info, parent=record_dict, default=default) record_dict[field_name] = field_value #if (field_name in defaults) and defaults[field_name] == field_value: # print '*** You can remove these lines:', field_name, field_value @@ -412,7 +410,7 @@ class YamlInterpreter(object): for field_name, expression in fields.items(): if field_name in record_dict: continue - field_value = self._eval_field(model, field_name, expression, default=False, fields_view_get=fields_view_get) + field_value = self._eval_field(model, field_name, expression, default=False) record_dict[field_name] = field_value return record_dict @@ -443,7 +441,7 @@ class YamlInterpreter(object): def process_eval(self, node): return eval(node.expression, self.eval_context) - def _eval_field(self, model, field_name, expression, view=False, parent={}, default=True, fields_view_get=None): + def _eval_field(self, model, field_name, expression, view_info=False, parent={}, default=True): # TODO this should be refactored as something like model.get_field() in bin/osv if field_name in model._columns: column = model._columns[field_name] @@ -464,7 +462,7 @@ class YamlInterpreter(object): value = self.get_id(expression) elif column._type == "one2many": other_model = self.get_model(column._obj) - value = [(0, 0, self._create_record(other_model, fields, view, parent, default=default, fields_view_get=fields_view_get)) for fields in expression] + value = [(0, 0, self._create_record(other_model, fields, view_info, parent, default=default)) for fields in expression] elif column._type == "many2many": ids = [self.get_id(xml_id) for xml_id in expression] value = [(6, 0, ids)] From 4d35720a57190f21edac89d1755d3d990c79fd83 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 1 Oct 2012 17:44:49 +0200 Subject: [PATCH 166/612] [IMP] translation import/export: more cleanup bzr revid: odo@openerp.com-20121001154449-146dte5i8ge1y1pj --- .../module/wizard/base_export_language.py | 16 ++------ .../wizard/base_export_language_view.xml | 4 +- .../module/wizard/base_import_language.py | 39 ++++++++----------- .../wizard/base_import_language_view.xml | 2 +- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/openerp/addons/base/module/wizard/base_export_language.py b/openerp/addons/base/module/wizard/base_export_language.py index 80cb2d70292..95f1d85bf6c 100644 --- a/openerp/addons/base/module/wizard/base_export_language.py +++ b/openerp/addons/base/module/wizard/base_export_language.py @@ -45,7 +45,6 @@ class base_language_export(osv.osv_memory): ('tgz', 'TGZ Archive')], 'File Format', required=True), 'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules To Export', domain=[('state','=','installed')]), 'data': fields.binary('File', readonly=True), - 'advice': fields.text('Note', readonly=True), 'state': fields.selection([('choose', 'choose'), # choose language ('get', 'get')]) # get the file } @@ -62,18 +61,10 @@ class base_language_export(osv.osv_memory): mods = map(lambda m: m.name, this.modules) or ['all'] mods.sort() buf = cStringIO.StringIO() - tools.trans_export(this.lang, mods, buf, this.format, cr) - if this.format == 'csv': - this.advice = _("Save this document as a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the last column before reimporting it.") - elif this.format == 'po': - if not lang: - this.format = 'pot' - this.advice = _("Save this document as a %s file and edit it with a PO editor or a text editor. The file encoding is UTF-8.") % ('.'+this.format,) - elif this.format == 'tgz': - this.advice = _('Save this document as a .tgz file. This archive contains UTF-8 %s files and may be uploaded to launchpad.') - filename = _('new') + tools.trans_export(lang, mods, buf, this.format, cr) + filename = 'new' if lang: - filename = get_iso_codes(this.lang) + filename = get_iso_codes(lang) elif len(mods) == 1: filename = mods[0] this.name = "%s.%s" % (filename, this.format) @@ -81,7 +72,6 @@ class base_language_export(osv.osv_memory): buf.close() self.write(cr, uid, ids, {'state': 'get', 'data': out, - 'advice': this.advice, 'name':this.name}, context=context) return True diff --git a/openerp/addons/base/module/wizard/base_export_language_view.xml b/openerp/addons/base/module/wizard/base_export_language_view.xml index 2e50b3bed8f..cbf7104f957 100644 --- a/openerp/addons/base/module/wizard/base_export_language_view.xml +++ b/openerp/addons/base/module/wizard/base_export_language_view.xml @@ -2,10 +2,10 @@ - Translations Export + Export Translations base.language.export -
    + diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py index 6f09dc43d90..9c36c9d7c54 100644 --- a/openerp/addons/base/module/wizard/base_import_language.py +++ b/openerp/addons/base/module/wizard/base_import_language.py @@ -30,8 +30,8 @@ class base_language_import(osv.osv_memory): _name = "base.language.import" _description = "Language Import" _columns = { - 'name': fields.char('Language Name',size=64 , required=True), - 'code': fields.char('Code (eg:en__US)',size=5 , required=True), + 'name': fields.char('Language Name', size=64 , required=True), + 'code': fields.char('ISO Code', size=5, help="ISO Language and Country code, e.g. en_US", required=True), 'data': fields.binary('File', required=True), 'overwrite': fields.boolean('Overwrite Existing Terms', help="If you enable this option, existing translations (including custom ones) " @@ -39,30 +39,25 @@ class base_language_import(osv.osv_memory): } def import_lang(self, cr, uid, ids, context=None): - """ - Import Language - @param cr: the current row, from the database cursor. - @param uid: the current user’s ID for security checks. - @param ids: the ID or list of IDs - @param context: A standard dictionary - """ if context is None: context = {} - import_data = self.browse(cr, uid, ids)[0] - if import_data.overwrite: + this = self.browse(cr, uid, ids[0]) + if this.overwrite: context.update(overwrite=True) fileobj = TemporaryFile('w+') - fileobj.write(base64.decodestring(import_data.data)) - - # now we determine the file format - fileobj.seek(0) - first_line = fileobj.readline().strip().replace('"', '').replace(' ', '') - fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po' - fileobj.seek(0) - - tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name, context=context) - fileobj.close() - return {} + try: + fileobj.write(base64.decodestring(this.data)) + + # now we determine the file format + fileobj.seek(0) + first_line = fileobj.readline().strip().replace('"', '').replace(' ', '') + fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po' + fileobj.seek(0) + + tools.trans_load_data(cr, fileobj, fileformat, this.code, lang_name=this.name, context=context) + finally: + fileobj.close() + return True # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_import_language_view.xml b/openerp/addons/base/module/wizard/base_import_language_view.xml index 727de4e381b..5e2aada7766 100644 --- a/openerp/addons/base/module/wizard/base_import_language_view.xml +++ b/openerp/addons/base/module/wizard/base_import_language_view.xml @@ -8,7 +8,7 @@ - + From 7c1339928b1e69a17e84c66bd366144dec6fed8e Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Mon, 1 Oct 2012 17:46:05 +0200 Subject: [PATCH 167/612] Removed day by day bzr revid: nicolas.vanhoren@openerp.com-20121001154605-nemay3pze49ejjld --- .../hr_timesheet_sheet/hr_timesheet_sheet.py | 157 +----------------- .../hr_timesheet_sheet_view.xml | 17 +- 2 files changed, 8 insertions(+), 166 deletions(-) diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index 13c11cf72c7..1c29a4e736f 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -27,80 +27,6 @@ from osv import fields, osv from tools.translate import _ import netsvc -class one2many_mod2(fields.one2many): - def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): - if context is None: - context = {} - - if values is None: - values = {} - - # res6 = {id: date_current, ...} - res6 = dict([(rec['id'], rec['date_current']) - for rec in obj.read(cr, user, ids, ['date_current'], context=context)]) - - dom = [] - for c, id in enumerate(ids): - if id in res6: - if c: # skip first - dom.insert(0 ,'|') - dom.append('&') - dom.append('&') - dom.append(('name', '>=', res6[id])) - dom.append(('name', '<=', res6[id])) - dom.append(('sheet_id', '=', id)) - - ids2 = obj.pool.get(self._obj).search(cr, user, dom, limit=self._limit) - - res = {} - for i in ids: - res[i] = [] - - for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_read'): - if r[self._fields_id]: - res[r[self._fields_id][0]].append(r['id']) - return res - - def set(self, cr, obj, id, field, values, user=None, context=None): - if context is None: - context = {} - - context = context.copy() - context['sheet_id'] = id - return super(one2many_mod2, self).set(cr, obj, id, field, values, user=user, context=context) - - -class one2many_mod(fields.one2many): - def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): - if context is None: - context = {} - - if values is None: - values = {} - - - res5 = obj.read(cr, user, ids, ['date_current'], context=context) - res6 = {} - for r in res5: - res6[r['id']] = r['date_current'] - - ids2 = [] - for id in ids: - dom = [] - if id in res6: - dom = [('date', '=', res6[id]), ('sheet_id', '=', id)] - ids2.extend(obj.pool.get(self._obj).search(cr, user, - dom, limit=self._limit)) - res = {} - for i in ids: - res[i] = [] - for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, - [self._fields_id], context=context, load='_classic_read'): - if r[self._fields_id]: - res[r[self._fields_id][0]].append(r['id']) - - return res - class hr_timesheet_sheet(osv.osv): _name = "hr_timesheet_sheet.sheet" _inherit = "mail.thread" @@ -111,8 +37,7 @@ class hr_timesheet_sheet(osv.osv): def _total_attendances(self, cr, uid, ids, name, args, context=None): """ Get the total attendance for the timesheets Returns a dict like : - {id: {'date_current': '2011-06-17', - 'total_per_day': {day: timedelta, ...}, + {id: {'total_per_day': {day: timedelta, ...}, }, ... } @@ -122,7 +47,6 @@ class hr_timesheet_sheet(osv.osv): res = {} for sheet_id in ids: sheet = self.browse(cr, uid, sheet_id, context=context) - date_current = sheet.date_current # field attendances_ids of hr_timesheet_sheet.sheet only # returns attendances of timesheet's current date attendance_ids = attendance_obj.search(cr, uid, [('sheet_id', '=', sheet_id)], context=context) @@ -143,20 +67,7 @@ class hr_timesheet_sheet(osv.osv): else: total_attendance[day] += attendance_interval - # if the delta is negative, it means that a sign out is missing - # in a such case, we want to have the time to the end of the day - # for a past date, and the time to now for the current date - if total_attendance[day] < timedelta(0): - if day == date_current: - now = datetime.now() - total_attendance[day] += timedelta(hours=now.hour, - minutes=now.minute, - seconds=now.second) - else: - total_attendance[day] += timedelta(days=1) - - res[sheet_id] = {'date_current': date_current, - 'total_per_day': total_attendance} + res[sheet_id] = {'total_per_day': total_attendance} return res def _total_timesheet(self, cr, uid, ids, name, args, context=None): @@ -210,24 +121,16 @@ class hr_timesheet_sheet(osv.osv): all_attendances_sheet = all_timesheet_attendances[id] - date_current = all_attendances_sheet['date_current'] total_attendances_sheet = all_attendances_sheet['total_per_day'] total_attendances_all_days = sum_all_days(total_attendances_sheet) - total_attendances_day = total_attendances_sheet.get(date_current, timedelta(seconds=0)) total_timesheets_sheet = all_timesheet_lines[id] total_timesheets_all_days = sum_all_days(total_timesheets_sheet) - total_timesheets_day = total_timesheets_sheet.get(date_current, timedelta(seconds=0)) total_difference_all_days = total_attendances_all_days - total_timesheets_all_days - total_difference_day = total_attendances_day - total_timesheets_day res[id]['total_attendance'] = timedelta_to_hours(total_attendances_all_days) res[id]['total_timesheet'] = timedelta_to_hours(total_timesheets_all_days) res[id]['total_difference'] = timedelta_to_hours(total_difference_all_days) - - res[id]['total_attendance_day'] = timedelta_to_hours(total_attendances_day) - res[id]['total_timesheet_day'] = timedelta_to_hours(total_timesheets_day) - res[id]['total_difference_day'] = timedelta_to_hours(total_difference_day) return res def check_employee_attendance_state(self, cr, uid, sheet_id, context=None): @@ -277,44 +180,6 @@ class hr_timesheet_sheet(osv.osv): raise osv.except_osv(_('Warning!'), _('Please verify that the total difference of the sheet is lower than %.2f.') %(di,)) return True - def date_today(self, cr, uid, ids, context=None): - for sheet in self.browse(cr, uid, ids, context=context): - if datetime.today() <= datetime.strptime(sheet.date_from, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_from,}, context=context) - elif datetime.now() >= datetime.strptime(sheet.date_to, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_to,}, context=context) - else: - self.write(cr, uid, [sheet.id], {'date_current': time.strftime('%Y-%m-%d')}, context=context) - return True - - def date_previous(self, cr, uid, ids, context=None): - for sheet in self.browse(cr, uid, ids, context=context): - if datetime.strptime(sheet.date_current, '%Y-%m-%d') <= datetime.strptime(sheet.date_from, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_from,}, context=context) - else: - self.write(cr, uid, [sheet.id], { - 'date_current': (datetime.strptime(sheet.date_current, '%Y-%m-%d') + relativedelta(days=-1)).strftime('%Y-%m-%d'), - }, context=context) - return True - - def date_next(self, cr, uid, ids, context=None): - for sheet in self.browse(cr, uid, ids, context=context): - if datetime.strptime(sheet.date_current, '%Y-%m-%d') >= datetime.strptime(sheet.date_to, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_to,}, context=context) - else: - self.write(cr, uid, [sheet.id], { - 'date_current': (datetime.strptime(sheet.date_current, '%Y-%m-%d') + relativedelta(days=1)).strftime('%Y-%m-%d'), - }, context=context) - return True - - def button_dummy(self, cr, uid, ids, context=None): - for sheet in self.browse(cr, uid, ids, context=context): - if datetime.strptime(sheet.date_current, '%Y-%m-%d') <= datetime.strptime(sheet.date_from, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_from,}, context=context) - elif datetime.strptime(sheet.date_current, '%Y-%m-%d') >= datetime.strptime(sheet.date_to, '%Y-%m-%d'): - self.write(cr, uid, [sheet.id], {'date_current': sheet.date_to,}, context=context) - return True - def attendance_action_change(self, cr, uid, ids, context=None): hr_employee = self.pool.get('hr.employee') employee_ids = [] @@ -329,14 +194,13 @@ class hr_timesheet_sheet(osv.osv): 'user_id': fields.related('employee_id', 'user_id', type="many2one", relation="res.users", store=True, string="User", required=False, readonly=True),#fields.many2one('res.users', 'User', required=True, select=1, states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}), 'date_from': fields.date('Date from', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}), 'date_to': fields.date('Date to', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}), - 'date_current': fields.date('Current date', required=True, select=1), - 'timesheet_ids' : one2many_mod('hr.analytic.timesheet', 'sheet_id', - 'Timesheet lines', domain=[('date', '=', time.strftime('%Y-%m-%d'))], + 'timesheet_ids' : fields.one2many('hr.analytic.timesheet', 'sheet_id', + 'Timesheet lines', readonly=True, states={ 'draft': [('readonly', False)], 'new': [('readonly', False)]} ), - 'attendances_ids' : one2many_mod2('hr.attendance', 'sheet_id', 'Attendances'), + 'attendances_ids' : fields.one2many('hr.attendance', 'sheet_id', 'Attendances'), 'state' : fields.selection([ ('new', 'New'), ('draft','Open'), @@ -346,9 +210,6 @@ class hr_timesheet_sheet(osv.osv): \n* The \'Confirmed\' state is used for to confirm the timesheet by user. \ \n* The \'Done\' state is used when users timesheet is accepted by his/her senior.'), 'state_attendance' : fields.related('employee_id', 'state', type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Current Status', readonly=True), - 'total_attendance_day': fields.function(_total, method=True, string='Total Attendance', multi="_total"), - 'total_timesheet_day': fields.function(_total, method=True, string='Total Timesheet', multi="_total"), - 'total_difference_day': fields.function(_total, method=True, string='Difference', multi="_total"), 'total_attendance': fields.function(_total, method=True, string='Total Attendance', multi="_total"), 'total_timesheet': fields.function(_total, method=True, string='Total Timesheet', multi="_total"), 'total_difference': fields.function(_total, method=True, string='Difference', multi="_total"), @@ -386,7 +247,6 @@ class hr_timesheet_sheet(osv.osv): _defaults = { 'date_from' : _default_date_from, - 'date_current' : lambda *a: time.strftime('%Y-%m-%d'), 'date_to' : _default_date_to, 'state': 'new', 'employee_id': _default_employee, @@ -406,16 +266,9 @@ class hr_timesheet_sheet(osv.osv): return False return True - def _date_current_check(self, cr, uid, ids, context=None): - for sheet in self.browse(cr, uid, ids, context=context): - if sheet.date_current < sheet.date_from or sheet.date_current > sheet.date_to: - return False - return True - _constraints = [ (_sheet_date, 'You cannot have 2 timesheets that overlaps !\nPlease use the menu \'My Current Timesheet\' to avoid this problem.', ['date_from','date_to']), - (_date_current_check, 'You must select a Current date which is in the timesheet dates !', ['date_current']), ] def action_set_to_draft(self, cr, uid, ids, *args): diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml index 78fc997d15e..7dd2b9a1b88 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml @@ -76,19 +76,8 @@ - -
    -
    -
    -
    -
    - + @@ -105,9 +94,9 @@ - + - + From 7d46e337633ff4265642d8a7bf9a8a9157a80c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 1 Oct 2012 17:49:16 +0200 Subject: [PATCH 168/612] [IMP] css: animations for kanban notes bzr revid: fva@openerp.com-20121001154916-r5mq1z4icc54jmgz --- addons/web_kanban/static/src/css/kanban.css | 9 ++++++--- addons/web_kanban/static/src/css/kanban.sass | 14 ++++++++++++-- addons/web_kanban/static/src/js/kanban.js | 6 ++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index 6846171a82a..60e8eefcf37 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -9,7 +9,6 @@ .openerp .oe_kanban_view .ui-sortable-placeholder { border: 1px solid rgba(0, 0, 0, 0.1); visibility: visible !important; - height: 60px !important; } .openerp .oe_kanban_view .ui-sortable-helper { -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.3); @@ -19,6 +18,9 @@ -webkit-transform: rotate(3deg); -o-transform: rotate(3deg); -ms-transform: rotate(3deg); + -webkit-transition: -webkit-transform 100ms linear; + -moz-transition: -moz-transform 100ms linear; + transition: transform 100ms linear; } .openerp .oe_kanban_view .oe_kanban_left { float: left; @@ -364,17 +366,18 @@ border-bottom-color: rgba(0, 0, 0, 0.3); padding: 8px; display: block; + -webkit-transition: -webkit-transform, -webkit-box-shadow, border 200ms linear; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } -.openerp .oe_kanban_view .oe_kanban_card:hover, .openerp .oe_kanban_view .oe_kanban_quick_create:hover { +.openerp .oe_kanban_view .oe_kanban_card:not(.ui-sortable-helper):hover, .openerp .oe_kanban_view .oe_kanban_quick_create:not(.ui-sortable-helper):hover { border: 1px solid #7c7bad; -moz-box-shadow: 0 0 4px #7c7bad; -webkit-box-shadow: 0 0 4px #7c7bad; -box-shadow: 0 0 4px #7c7bad; } -.openerp .oe_kanban_view .oe_kanban_card:hover .oe_dropdown_kanban > span, .openerp .oe_kanban_view .oe_kanban_quick_create:hover .oe_dropdown_kanban > span { +.openerp .oe_kanban_view .oe_kanban_card:not(.ui-sortable-helper):hover .oe_dropdown_kanban > span, .openerp .oe_kanban_view .oe_kanban_quick_create:not(.ui-sortable-helper):hover .oe_dropdown_kanban > span { visibility: visible; } .openerp .oe_kanban_view .oe_kanban_card h3, .openerp .oe_kanban_view .oe_kanban_quick_create h3 { diff --git a/addons/web_kanban/static/src/css/kanban.sass b/addons/web_kanban/static/src/css/kanban.sass index 88b60134f24..1210e9bf640 100644 --- a/addons/web_kanban/static/src/css/kanban.sass +++ b/addons/web_kanban/static/src/css/kanban.sass @@ -37,6 +37,13 @@ -webkit-transform: $transform -o-transform: $transform -ms-transform: $transform + +@mixin transition($transition: all 200ms linear) + -webkit-transition: $transition + -moz-transition: $transition + -ms-transition: $transition + -o-transition: $transition + transition: $transition // }}} .openerp .oe_kanban_view @@ -49,10 +56,12 @@ .ui-sortable-placeholder border: 1px solid rgba(0,0,0,0.1) visibility: visible !important - height: 60px !important .ui-sortable-helper @include box-shadow(0 1px 10px rgba(0, 0, 0, 0.3)) @include transform(rotate(3deg)) + -webkit-transition: -webkit-transform 100ms linear + -moz-transition: -moz-transform 100ms linear + transition: transform 100ms linear .oe_kanban_left float: left .oe_kanban_right @@ -328,8 +337,9 @@ border-bottom-color: rgba(0,0,0,0.3) padding: 8px display: block + -webkit-transition: -webkit-transform, -webkit-box-shadow, border 200ms linear @include radius(4px) - &:hover + &:not(.ui-sortable-helper):hover border: 1px solid #7C7BAD @include box-shadow(0 0 4px #7C7BAD) .oe_dropdown_kanban > span diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index bd36dcbf4ba..d8e93efa580 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -309,8 +309,14 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ ui.item.find('*').on('click.prevent', function(ev) { return false; }); + ui.placeholder.height(ui.item.height()); + }, + revert: 150, + beforeStop: function(event,ui){ + console.log('beforeStop:',ui); }, stop: function(event, ui) { + console.log('stop:',ui); var record = ui.item.data('widget'); var old_index = self.currently_dragging.index; var new_index = ui.item.index(); From 2b07b4e35c5ee619eaf93a7bb4fb14a37e55fb0e Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 1 Oct 2012 18:08:54 +0200 Subject: [PATCH 169/612] [FIX] sale, sale_stock: yaml tests on product_id_change() + fix in that same function (type is defined in sale_stock now) bzr revid: qdp-launchpad@openerp.com-20121001160854-7d2xew5pol6u27b2 --- addons/sale/sale.py | 1 - addons/sale/sale_view.xml | 5 ++--- addons/sale/test/sale_order_demo.yml | 14 ++++++-------- addons/sale_stock/test/sale_order_onchange.yml | 14 ++++++-------- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 96f44d353d6..f9dc3c62281 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -899,7 +899,6 @@ class sale_order_line(osv.osv): fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False if update_tax: #The quantity only have changed result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id) - result.update({'type': product_obj.procure_method}) if not flag: result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner)[0][1] diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 23d2c556f40..620991d8053 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -200,8 +200,7 @@ -