diff options
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/base/i18n/base.pot | 6 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_mail_server.py | 2 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_qweb_fields.py | 6 | ||||
| -rw-r--r-- | odoo/addons/base/models/res_users.py | 38 | ||||
| -rw-r--r-- | odoo/addons/base/tests/test_ir_sequence_date_range.py | 2 | ||||
| -rw-r--r-- | odoo/addons/base/tests/test_user_has_group.py | 18 | ||||
| -rw-r--r-- | odoo/addons/base/views/ir_qweb_widget_templates.xml | 4 | ||||
| -rw-r--r-- | odoo/addons/base/views/res_partner_views.xml | 2 | ||||
| -rw-r--r-- | odoo/addons/base/wizard/base_language_install.py | 2 | ||||
| -rw-r--r-- | odoo/models.py | 2 |
10 files changed, 71 insertions, 11 deletions
diff --git a/odoo/addons/base/i18n/base.pot b/odoo/addons/base/i18n/base.pot index 5602a3b204c..dc5c2c677e4 100644 --- a/odoo/addons/base/i18n/base.pot +++ b/odoo/addons/base/i18n/base.pot @@ -7363,6 +7363,12 @@ msgstr "" #. module: base #: code:addons/base/models/ir_qweb_fields.py:610 #, python-format +msgid "Barcode symbology" +msgstr "" + +#. module: base +#: code:addons/base/models/ir_qweb_fields.py:603 +#, python-format msgid "Barcode type" msgstr "" diff --git a/odoo/addons/base/models/ir_mail_server.py b/odoo/addons/base/models/ir_mail_server.py index 9ab49f9e5c5..84dea41c5e2 100644 --- a/odoo/addons/base/models/ir_mail_server.py +++ b/odoo/addons/base/models/ir_mail_server.py @@ -126,7 +126,7 @@ def encode_rfc2822_address_header(header_text): return formataddr((name, email)) except UnicodeEncodeError: _logger.warning(_('Failed to encode the address %s\n' - 'from mail header:\n%s') % addr, header_text) + 'from mail header:\n%s') % (addr, header_text)) return "" addresses = getaddresses([pycompat.to_text(ustr(header_text))]) diff --git a/odoo/addons/base/models/ir_qweb_fields.py b/odoo/addons/base/models/ir_qweb_fields.py index 57e7f3891f5..dc520809f6e 100644 --- a/odoo/addons/base/models/ir_qweb_fields.py +++ b/odoo/addons/base/models/ir_qweb_fields.py @@ -607,7 +607,7 @@ class BarcodeConverter(models.AbstractModel): def get_available_options(self): options = super(BarcodeConverter, self).get_available_options() options.update( - type=dict(type='string', string=_('Barcode type'), description=_('Barcode type, eg: UPCA, EAN13, Code128'), default_value='Code128'), + symbology=dict(type='string', string=_('Barcode symbology'), description=_('Barcode type, eg: UPCA, EAN13, Code128'), default_value='Code128'), width=dict(type='integer', string=_('Width'), default_value=600), height=dict(type='integer', string=_('Height'), default_value=100), humanreadable=dict(type='integer', string=_('Human Readable'), default_value=0), @@ -616,9 +616,9 @@ class BarcodeConverter(models.AbstractModel): @api.model def value_to_html(self, value, options=None): - barcode_type = options.get('type', 'Code128') + barcode_symbology = options.get('symbology', 'Code128') barcode = self.env['ir.actions.report'].barcode( - barcode_type, + barcode_symbology, value, **{key: value for key, value in options.items() if key in ['width', 'height', 'humanreadable']}) return u'<img src="data:png;base64,%s">' % base64.b64encode(barcode).decode('ascii') diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 204ce97f6fe..2fb44ff6382 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -405,11 +405,44 @@ class Users(models.Model): @api.multi @api.constrains('groups_id') def _check_one_user_type(self): - for user in self: - if len(user.groups_id.filtered(lambda x: x.category_id.xml_id == 'base.module_category_user_type')) > 1: + """We check that no users are both portal and users (same with public). + This could typically happen because of implied groups. + """ + user_types_category = self.env.ref('base.module_category_user_type', raise_if_not_found=False) + user_types_groups = self.env['res.groups'].search( + [('category_id', '=', user_types_category.id)]) if user_types_category else False + if user_types_groups: # needed at install + if self._has_multiple_groups(user_types_groups.ids): raise ValidationError(_('The user cannot have more than one user types.')) @api.multi + def _has_multiple_groups(self, group_ids): + """The method is not fast if the list of ids is very long; + so we rather check all users than limit to the size of the group + :param group_ids: list of group ids + :return: boolean: is there at least a user in at least 2 of the provided groups + """ + if group_ids: + args = [tuple(group_ids)] + if len(self.ids) == 1: + where_clause = "AND r.uid = %s" + args.append(self.id) + else: + where_clause = "" # default; we check ALL users (actually pretty efficient) + query = """ + SELECT 1 FROM res_groups_users_rel WHERE EXISTS( + SELECT r.uid + FROM res_groups_users_rel r + WHERE r.gid IN %s""" + where_clause + """ + GROUP BY r.uid HAVING COUNT(r.gid) > 1 + ) + """ + self.env.cr.execute(query, args) + return bool(self.env.cr.fetchall()) + else: + return False + + @api.multi def toggle_active(self): for user in self: if not user.active and not user.partner_id.active: @@ -951,6 +984,7 @@ class GroupsImplied(models.Model): JOIN group_imply i ON (r.gid = i.hid) WHERE i.gid = %(gid)s """, dict(gid=group.id)) + self._check_one_user_type() return res class UsersImplied(models.Model): diff --git a/odoo/addons/base/tests/test_ir_sequence_date_range.py b/odoo/addons/base/tests/test_ir_sequence_date_range.py index 08729f3a072..43e218f1189 100644 --- a/odoo/addons/base/tests/test_ir_sequence_date_range.py +++ b/odoo/addons/base/tests/test_ir_sequence_date_range.py @@ -24,7 +24,7 @@ class TestIrSequenceDateRangeStandard(SingleTransactionCase): year = date.today().year - 1 january = lambda d: date(year, 1, d) - seq16 = self.env['ir.sequence'].with_context({'ir_sequence_date': january(16)}) + seq16 = self.env['ir.sequence'].with_context(ir_sequence_date=january(16)) n = seq16.next_by_code('test_sequence_date_range') self.assertEqual(n, '1') n = seq16.next_by_code('test_sequence_date_range') diff --git a/odoo/addons/base/tests/test_user_has_group.py b/odoo/addons/base/tests/test_user_has_group.py index 70169a6f99a..18326607f06 100644 --- a/odoo/addons/base/tests/test_user_has_group.py +++ b/odoo/addons/base/tests/test_user_has_group.py @@ -143,3 +143,21 @@ class TestHasGroup(TransactionCase): }) with self.assertRaises(ValidationError): self.grp_internal.users = [(4, test_user.id)] + + def test_two_user_types_implied_groups(self): + """Contrarily to test_two_user_types, we simply add an implied_id to a group. + This will trigger the addition of the relevant users to the relevant groups; + if, say, this was done in SQL and thus bypassing the ORM, it would bypass the constraints + and thus give us a case uncovered by the aforementioned test. + """ + grp_test = self.env["res.groups"].create( + {"name": "test", "implied_ids": [(6, 0, [self.grp_internal.id])]}) + + test_user = self.env['res.users'].create({ + 'login': 'test_user_portal', + 'name': "Test User with one user types", + 'groups_id': [(6, 0, [grp_test.id])] + }) + + with self.assertRaises(ValidationError): + grp_test.write({'implied_ids': [(4, self.grp_portal.id)]}) diff --git a/odoo/addons/base/views/ir_qweb_widget_templates.xml b/odoo/addons/base/views/ir_qweb_widget_templates.xml index 47bf04a62ff..4f141cadb71 100644 --- a/odoo/addons/base/views/ir_qweb_widget_templates.xml +++ b/odoo/addons/base/views/ir_qweb_widget_templates.xml @@ -13,7 +13,7 @@ </div> </template> <template id="contact"> - <address t-ignore="true" class="d-inline-block mb-0" itemscope="itemscope" itemtype="http://schema.org/Organization"> + <address t-ignore="true" class="mb-0" itemscope="itemscope" itemtype="http://schema.org/Organization"> <div t-if="not (('name' in fields) or (address and 'address' in fields) or (city and 'city' in fields) or (mobile and 'mobile' in fields) or (website and 'website' in fields) or (email and 'email' in fields))" class="css_non_editable_mode_hidden"> --<span class="text-muted" t-esc="name"/>-- </div> @@ -23,7 +23,7 @@ <div itemprop="address" itemscope="itemscope" itemtype="http://schema.org/PostalAddress"> <div t-if="address and 'address' in fields" class="d-flex align-items-baseline"> <i t-if="not options.get('no_marker')" class="fa fa-map-marker fa-fw" role="img" aria-label="Address" title="Address"/> - <span itemprop="streetAddress" t-raw="address.replace('\n', options.get('no_tag_br') and ', ' or ('<br/>%s' % ('' if options.get('no_marker') else '')))"/> + <div class="w-100" itemprop="streetAddress" t-raw="address.replace('\n', options.get('no_tag_br') and ', ' or ('<br/>%s' % ('' if options.get('no_marker') else '')))"/> </div> <div t-if="city and 'city' in fields" class="d-flex align-items-baseline"> <i t-if="not options.get('no_marker')" class="fa fa-map-marker fa-fw" role="img" aria-label="Address" title="Address"/> diff --git a/odoo/addons/base/views/res_partner_views.xml b/odoo/addons/base/views/res_partner_views.xml index f8c9ba3d7af..b6d3d414be8 100644 --- a/odoo/addons/base/views/res_partner_views.xml +++ b/odoo/addons/base/views/res_partner_views.xml @@ -519,7 +519,7 @@ <img class="o_kanban_image_inner_pic" t-if="record.parent_id.raw_value" t-att-alt="record.parent_id.value" t-att-src="kanban_image('res.partner', 'image_small', record.parent_id.raw_value)"/> </div> </t> - <t t-else=""> + <t t-elif="record.image_medium.raw_value"> <t t-set="placeholder" t-value="'/base/static/img/company_image.png'"/> <div class="o_kanban_image_fill_left o_kanban_image_full" t-attf-style="background-image: url(#{kanban_image('res.partner', 'image_medium', record.id.raw_value, placeholder)})" role="img"/> </t> diff --git a/odoo/addons/base/wizard/base_language_install.py b/odoo/addons/base/wizard/base_language_install.py index 438803ee388..376d1fd5751 100644 --- a/odoo/addons/base/wizard/base_language_install.py +++ b/odoo/addons/base/wizard/base_language_install.py @@ -35,6 +35,8 @@ class BaseLanguageInstall(models.TransientModel): mods = self.env['ir.module.module'].search([('state', '=', 'installed')]) mods.with_context(overwrite=self.overwrite)._update_translations(self.lang) self.state = 'done' + self.env.cr.execute('ANALYZE ir_translation') + return { 'name': _('Language Pack'), 'view_type': 'form', diff --git a/odoo/models.py b/odoo/models.py index 7d6962f0e23..36ee8d1495a 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -5306,7 +5306,7 @@ Fields: target0 = Model.browse(i for [i] in self.env.cr.fetchall()) else: env = self.env(user=SUPERUSER_ID, context={'active_test': False}) - target0 = env[model_name].search([(path, 'in', self.ids)]) + target0 = env[model_name].search([(path, 'in', self.ids)], order='id') target0 = target0.with_env(self.env) # prepare recomputation for each field on linked records for field in stored: |
