1# -*- coding: utf-8 -*- 2# Part of Odoo. See LICENSE file for full copyright and licensing details. 3import logging 4 5from odoo import api, fields, models, tools, _ 6from odoo.exceptions import ValidationError 7from odoo.http import request 8 9_logger = logging.getLogger(__name__) 10 11 12class ResUsers(models.Model): 13 _inherit = 'res.users' 14 15 website_id = fields.Many2one('website', related='partner_id.website_id', store=True, related_sudo=False, readonly=False) 16 17 _sql_constraints = [ 18 # Partial constraint, complemented by a python constraint (see below). 19 ('login_key', 'unique (login, website_id)', 'You can not have two users with the same login!'), 20 ] 21 22 def _has_unsplash_key_rights(self): 23 self.ensure_one() 24 if self.has_group('website.group_website_designer'): 25 return True 26 return super(ResUsers, self)._has_unsplash_key_rights() 27 28 @api.constrains('login', 'website_id') 29 def _check_login(self): 30 """ Do not allow two users with the same login without website """ 31 self.flush(['login', 'website_id']) 32 self.env.cr.execute( 33 """SELECT login 34 FROM res_users 35 WHERE login IN (SELECT login FROM res_users WHERE id IN %s AND website_id IS NULL) 36 AND website_id IS NULL 37 GROUP BY login 38 HAVING COUNT(*) > 1 39 """, 40 (tuple(self.ids),) 41 ) 42 if self.env.cr.rowcount: 43 raise ValidationError(_('You can not have two users with the same login!')) 44 45 @api.model 46 def _get_login_domain(self, login): 47 website = self.env['website'].get_current_website() 48 return super(ResUsers, self)._get_login_domain(login) + website.website_domain() 49 50 @api.model 51 def _get_login_order(self): 52 return 'website_id, ' + super(ResUsers, self)._get_login_order() 53 54 @api.model 55 def _signup_create_user(self, values): 56 current_website = self.env['website'].get_current_website() 57 if request and current_website.specific_user_account: 58 values['company_id'] = current_website.company_id.id 59 values['company_ids'] = [(4, current_website.company_id.id)] 60 values['website_id'] = current_website.id 61 new_user = super(ResUsers, self)._signup_create_user(values) 62 return new_user 63 64 @api.model 65 def _get_signup_invitation_scope(self): 66 current_website = self.env['website'].get_current_website() 67 return current_website.auth_signup_uninvited or super(ResUsers, self)._get_signup_invitation_scope() 68 69 @classmethod 70 def authenticate(cls, db, login, password, user_agent_env): 71 """ Override to link the logged in user's res.partner to website.visitor. 72 If both a request-based visitor and a user-based visitor exist we try 73 to update them (have same partner_id), and move sub records to the main 74 visitor (user one). Purpose is to try to keep a main visitor with as 75 much sub-records (tracked pages, leads, ...) as possible. """ 76 uid = super(ResUsers, cls).authenticate(db, login, password, user_agent_env) 77 if uid: 78 with cls.pool.cursor() as cr: 79 env = api.Environment(cr, uid, {}) 80 visitor_sudo = env['website.visitor']._get_visitor_from_request() 81 if visitor_sudo: 82 user_partner = env.user.partner_id 83 other_user_visitor_sudo = env['website.visitor'].with_context(active_test=False).sudo().search( 84 [('partner_id', '=', user_partner.id), ('id', '!=', visitor_sudo.id)], 85 order='last_connection_datetime DESC', 86 ) # current 13.3 state: 1 result max as unique visitor / partner 87 if other_user_visitor_sudo: 88 visitor_main = other_user_visitor_sudo[0] 89 other_visitors = other_user_visitor_sudo[1:] # normally void 90 (visitor_sudo + other_visitors)._link_to_visitor(visitor_main, keep_unique=True) 91 visitor_main.name = user_partner.name 92 visitor_main.active = True 93 visitor_main._update_visitor_last_visit() 94 else: 95 if visitor_sudo.partner_id != user_partner: 96 visitor_sudo._link_to_partner( 97 user_partner, 98 update_values={'partner_id': user_partner.id}) 99 visitor_sudo._update_visitor_last_visit() 100 return uid 101