summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-06-15 18:44:16 +0200
committerChristophe Simonis <chs@odoo.com>2017-06-15 18:44:16 +0200
commit1b50c829ef383705647d0c2df7c89e9051ec40fb (patch)
tree036df47c7cf94424f04d7ff9dac371fb79e2b1e4 /odoo
parent0c2e018d4c416d0f47a3b64f1c28ce067dbab291 (diff)
parent9713dc2e1f515b1260eaf26ec6bbfd5443f37d65 (diff)
[MERGE] forward port branch saas-15 up to 9713dc2e1f5
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/base/ir/ir_translation.py12
-rw-r--r--odoo/addons/base/tests/test_translate.py69
-rw-r--r--odoo/http.py2
-rw-r--r--odoo/models.py10
-rw-r--r--odoo/sql_db.py13
5 files changed, 97 insertions, 9 deletions
diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py
index 997f4a611df..50ba56fcf23 100644
--- a/odoo/addons/base/ir/ir_translation.py
+++ b/odoo/addons/base/ir/ir_translation.py
@@ -544,16 +544,18 @@ class IrTranslation(models.Model):
record = trans.env[mname].browse(trans.res_id)
field = record._fields[fname]
if callable(field.translate):
- # check whether applying (trans.src -> trans.value) then
- # (trans.value -> trans.src) gives the original value back
+ src = trans.src
+ val = trans.value.strip()
+ # check whether applying (src -> val) then (val -> src)
+ # gives the original value back
value0 = field.translate(lambda term: None, record[fname])
- value1 = field.translate({trans.src: trans.value}.get, value0)
+ value1 = field.translate({src: val}.get, value0)
# don't check the reverse if no translation happened
if value0 == value1:
continue
- value2 = field.translate({trans.value: trans.src}.get, value1)
+ value2 = field.translate({val: src}.get, value1)
if value2 != value0:
- raise ValidationError(_("Translation is not valid:\n%s") % trans.value)
+ raise ValidationError(_("Translation is not valid:\n%s") % val)
@api.model
def create(self, vals):
diff --git a/odoo/addons/base/tests/test_translate.py b/odoo/addons/base/tests/test_translate.py
index de607798a82..328906c89c2 100644
--- a/odoo/addons/base/tests/test_translate.py
+++ b/odoo/addons/base/tests/test_translate.py
@@ -270,3 +270,72 @@ class TestTranslation(TransactionCase):
categories = padawans_fr.search([('id', 'in', [self.customers.id, padawans.id])], order='name')
self.assertEqual(categories.ids, [padawans.id, self.customers.id],
"Search ordered by translated name should return Padawans (Apprentis) before Customers (Clients)")
+
+
+class TestXMLTranslation(TransactionCase):
+ def setUp(self):
+ super(TestXMLTranslation, self).setUp()
+ self.env['ir.translation'].load_module_terms(['base'], ['fr_FR'])
+
+ def test_copy(self):
+ """ Create a simple view, fill in translations, and copy it. """
+ env_en = self.env(context={})
+ env_fr = self.env(context={'lang': 'fr_FR'})
+
+ archf = '<form string="%s"><div>%s</div><div>%s</div></form>'
+ terms_en = ('Knife', 'Fork', 'Spoon')
+ terms_fr = ('Couteau', 'Fourchette', 'Cuiller')
+ view0 = self.env['ir.ui.view'].create({
+ 'name': 'test',
+ 'model': 'res.partner',
+ 'arch': archf % terms_en,
+ })
+ for src, value in zip(terms_en, terms_fr):
+ self.env['ir.translation'].create({
+ 'type': 'model',
+ 'name': 'ir.ui.view,arch_db',
+ 'lang': 'fr_FR',
+ 'res_id': view0.id,
+ 'src': src,
+ 'value': value,
+ })
+
+ # check translated field
+ self.assertEqual(view0.with_env(env_en).arch_db, archf % terms_en)
+ self.assertEqual(view0.with_env(env_fr).arch_db, archf % terms_fr)
+
+ # copy without lang
+ view1 = view0.with_env(env_en).copy({})
+ self.assertEqual(view1.with_env(env_en).arch_db, archf % terms_en)
+ self.assertEqual(view1.with_env(env_fr).arch_db, archf % terms_fr)
+
+ # copy with lang='fr_FR'
+ view2 = view0.with_env(env_fr).copy({})
+ self.assertEqual(view2.with_env(env_en).arch_db, archf % terms_en)
+ self.assertEqual(view2.with_env(env_fr).arch_db, archf % terms_fr)
+
+ # copy with lang='fr_FR' and translate=html_translate
+ self.patch(type(self.env['ir.ui.view']).arch_db, 'translate', html_translate)
+ view3 = view0.with_env(env_fr).copy({})
+ self.assertEqual(view3.with_env(env_en).arch_db, archf % terms_en)
+ self.assertEqual(view3.with_env(env_fr).arch_db, archf % terms_fr)
+
+ def test_spaces(self):
+ """ Create translations where value has surrounding spaces. """
+ archf = '<form string="%s"><div>%s</div><div>%s</div></form>'
+ terms_en = ('Knife', 'Fork', 'Spoon')
+ terms_fr = (' Couteau', 'Fourchette ', ' Cuiller ')
+ view0 = self.env['ir.ui.view'].create({
+ 'name': 'test',
+ 'model': 'res.partner',
+ 'arch': archf % terms_en,
+ })
+ for src, value in zip(terms_en, terms_fr):
+ self.env['ir.translation'].create({
+ 'type': 'model',
+ 'name': 'ir.ui.view,arch_db',
+ 'lang': 'fr_FR',
+ 'res_id': view0.id,
+ 'src': src,
+ 'value': value,
+ })
diff --git a/odoo/http.py b/odoo/http.py
index 0b3ad105e39..c32d0178b8a 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -167,6 +167,8 @@ def redirect_with_hash(url, code=303):
# See extensive test page at http://greenbytes.de/tech/tc/httpredirects/
if request.httprequest.user_agent.browser in ('firefox',):
return werkzeug.utils.redirect(url, code)
+ if urlparse.urlparse(url, scheme='http').scheme not in ('http', 'https'):
+ url = 'http://' + url
url = url.replace("'", "%27").replace("<", "%3C")
return "<html><head><script>window.location = '%s' + location.hash;</script></head></html>" % url
diff --git a/odoo/models.py b/odoo/models.py
index 518e0f7b859..b0b8361691a 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -3812,16 +3812,18 @@ class BaseModel(object):
# for translatable fields we copy their translations
trans_name, source_id, target_id = get_trans(field, old, new)
domain = [('name', '=', trans_name), ('res_id', '=', source_id)]
+ new_val = new_wo_lang[name]
+ if old.env.lang:
+ # the new value *without lang* must be the old value without lang
+ new_wo_lang[name] = old_wo_lang[name]
for vals in Translation.search_read(domain):
del vals['id']
del vals['source'] # remove source to avoid triggering _set_src
del vals['module'] # duplicated vals is not linked to any module
vals['res_id'] = target_id
if vals['lang'] == old.env.lang and field.translate is True:
- # 'source' to force the call to _set_src
- # 'value' needed if value is changed in copy(), want to see the new_value
- vals['source'] = old_wo_lang[name]
- vals['value'] = new_wo_lang[name]
+ # the value should be the new value (given by copy())
+ vals['value'] = new_val
Translation.create(vals)
@api.multi
diff --git a/odoo/sql_db.py b/odoo/sql_db.py
index 9a438d387de..b4c69824ab2 100644
--- a/odoo/sql_db.py
+++ b/odoo/sql_db.py
@@ -54,6 +54,19 @@ psycopg2.extensions.register_type(psycopg2.extensions.new_type((700, 701, 1700,)
from . import tools
from .tools.func import frame_codeinfo
+
+from tools import parse_version as pv
+if pv(psycopg2.__version__) < pv('2.7'):
+ from psycopg2._psycopg import QuotedString
+ def adapt_string(adapted):
+ """Python implementation of psycopg/psycopg2#459 from v2.7"""
+ if '\x00' in adapted:
+ raise ValueError("A string literal cannot contain NUL (0x00) characters.")
+ return QuotedString(adapted)
+
+ psycopg2.extensions.register_adapter(str, adapt_string)
+ psycopg2.extensions.register_adapter(unicode, adapt_string)
+
from datetime import timedelta
import threading
from inspect import currentframe