diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-04-10 15:10:24 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-04-10 15:10:24 +0200 |
| commit | e145f2b0c8831ec8756307b6b70c82f8dcdcab54 (patch) | |
| tree | 93406d01e313cfecdeac03132c1cccb55ff05088 /odoo | |
| parent | 3f95b074e959f0f4ac93fbf4048c0c7276f2c17a (diff) | |
| parent | 2694174b410f14ca81f0681ff4ae6856ff459ced (diff) | |
[MERGE] forward port branch saas-12.2 up to 2694174b410
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/base/models/ir_mail_server.py | 2 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_model.py | 11 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_module.py | 9 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_translation.py | 41 | ||||
| -rw-r--r-- | odoo/addons/base/models/res_currency.py | 2 | ||||
| -rw-r--r-- | odoo/fields.py | 6 | ||||
| -rw-r--r-- | odoo/models.py | 5 |
7 files changed, 72 insertions, 4 deletions
diff --git a/odoo/addons/base/models/ir_mail_server.py b/odoo/addons/base/models/ir_mail_server.py index b7597ebaa77..6773e1f61cc 100644 --- a/odoo/addons/base/models/ir_mail_server.py +++ b/odoo/addons/base/models/ir_mail_server.py @@ -483,6 +483,8 @@ class IrMailServer(models.Model): # do not quit() a pre-established smtp_session if not smtp_session: smtp.quit() + except smtplib.SMTPServerDisconnected: + raise except Exception as e: params = (ustr(smtp_server), e.__class__.__name__, ustr(e)) msg = _("Mail delivery failed via SMTP server '%s'.\n%s: %s") % params diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index eb03dfcafcd..b7a923dfa49 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -185,6 +185,11 @@ class IrModel(models.Model): self._cr.execute('DROP VIEW "%s"' % table) elif kind == 'r': self._cr.execute('DROP TABLE "%s" CASCADE' % table) + # discard all translations for this model + self._cr.execute(""" + DELETE FROM ir_translation + WHERE type IN ('model', 'model_terms') AND name LIKE %s + """, [model.model + ',%']) else: _logger.warning('The model %s could not be dropped because it did not exist in the registry.', model.model) return True @@ -574,6 +579,12 @@ class IrModelFields(models.Model): tables_to_drop.add(rel_name) if field.state == 'manual' and is_model: model._pop_field(field.name) + if field.translate: + # discard all translations for this field + self._cr.execute(""" + DELETE FROM ir_translation + WHERE type IN ('model', 'model_terms') AND name=%s + """, ['%s,%s' % (field.model, field.name)]) if tables_to_drop: # drop the relation tables that are not used by other fields diff --git a/odoo/addons/base/models/ir_module.py b/odoo/addons/base/models/ir_module.py index 27c81dd2702..ddccfb2c3ca 100644 --- a/odoo/addons/base/models/ir_module.py +++ b/odoo/addons/base/models/ir_module.py @@ -19,6 +19,7 @@ from docutils.core import publish_string from docutils.transforms import Transform, writer_aux from docutils.writers.html4css1 import Writer import lxml.html +import psycopg2 import odoo from odoo import api, fields, models, modules, tools, _ @@ -542,6 +543,14 @@ class Module(models.Model): @api.multi def _button_immediate_function(self, function): + try: + # This is done because the installation/uninstallation/upgrade can modify a currently + # running cron job and prevent it from finishing, and since the ir_cron table is locked + # during execution, the lock won't be released until timeout. + self._cr.execute("SELECT * FROM ir_cron FOR UPDATE NOWAIT") + except psycopg2.OperationalError: + raise UserError(_("The server is busy right now, module operations are not possible at" + " this time, please try again later.")) function(self) self._cr.commit() diff --git a/odoo/addons/base/models/ir_translation.py b/odoo/addons/base/models/ir_translation.py index 2d9744abada..bf560adf467 100644 --- a/odoo/addons/base/models/ir_translation.py +++ b/odoo/addons/base/models/ir_translation.py @@ -670,6 +670,47 @@ class IrTranslation(models.Model): self._modified_model(field.model_name) @api.model + def _upsert_translations(self, vals_list): + """ Insert or update translations of type 'model' or 'model_terms'. + + This method is used for creations of translations where the given + ``vals_list`` is trusted to be the right values and potential + conflicts should be updated to the new given value. + """ + rows_by_type = defaultdict(list) + for vals in vals_list: + rows_by_type[vals['type']].append(( + vals['name'], vals['lang'], vals['res_id'], vals['src'], vals['type'], + vals.get('module'), vals['value'], vals.get('state'), vals.get('comments'), + )) + + if rows_by_type['model']: + query = """ + INSERT INTO ir_translation (name, lang, res_id, src, type, + module, value, state, comments) + VALUES {} + ON CONFLICT (type, lang, name, res_id) WHERE type='model' + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = + (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, + EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; + """.format(", ".join(["%s"] * len(rows_by_type['model']))) + self.env.cr.execute(query, rows_by_type['model']) + + if rows_by_type['model_terms']: + query = """ + INSERT INTO ir_translation (name, lang, res_id, src, type, + module, value, state, comments) + VALUES {} + ON CONFLICT (type, name, lang, res_id, md5(src)) + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = + (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, + EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; + """.format(", ".join(["%s"] * len(rows_by_type['model_terms']))) + self.env.cr.execute(query, rows_by_type['model_terms']) + + @api.model def translate_fields(self, model, id, field=None): """ Open a view for translating the field(s) of the record (model, id). """ main_lang = 'en_US' diff --git a/odoo/addons/base/models/res_currency.py b/odoo/addons/base/models/res_currency.py index c75ddfe0021..09a6d019f38 100644 --- a/odoo/addons/base/models/res_currency.py +++ b/odoo/addons/base/models/res_currency.py @@ -115,7 +115,7 @@ class Currency(models.Model): fractional_value = int(parts[2] or 0) lang_code = self.env.context.get('lang') or self.env.user.lang - lang = self.env['res.lang'].search([('code', '=', lang_code)]) + lang = self.env['res.lang'].with_context(active_test=False).search([('code', '=', lang_code)]) amount_words = tools.ustr('{amt_value} {amt_word}').format( amt_value=_num2words(integer_value, lang=lang.iso_code), amt_word=self.currency_unit_label, diff --git a/odoo/fields.py b/odoo/fields.py index 16a13bedbe4..0f729ba924b 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -945,7 +945,11 @@ class Field(MetaField('DummyField', (object,), {})): """ indexname = '%s_%s_index' % (model._table, self.name) if self.index: - sql.create_index(model._cr, indexname, model._table, ['"%s"' % self.name]) + try: + with model._cr.savepoint(): + sql.create_index(model._cr, indexname, model._table, ['"%s"' % self.name]) + except psycopg2.OperationalError: + _schema.error("Unable to add index for %s", self) else: sql.drop_index(model._cr, indexname, model._table) diff --git a/odoo/models.py b/odoo/models.py index 7178f27f24c..8ebd58f4b1d 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -4311,11 +4311,12 @@ Fields: if vals['lang'] == old.env.lang and field.translate is True: # force a source if the new_val was not changed by copy override if new_val == old[name]: - vals['source'] = old_wo_lang[name] + new_wo_lang[name] = old_wo_lang[name] + vals['src'] = old_wo_lang[name] # the value should be the new value (given by copy()) vals['value'] = new_val vals_list.append(vals) - Translation.create(vals_list) + Translation._upsert_translations(vals_list) @api.multi @api.returns('self', lambda value: value.id) |
