diff --git a/addons/activeblue_ai/__init__.py b/addons/activeblue_ai/__init__.py index 0df9f4b..ac29b95 100644 --- a/addons/activeblue_ai/__init__.py +++ b/addons/activeblue_ai/__init__.py @@ -5,21 +5,52 @@ _logger = logging.getLogger(__name__) def _ensure_ai_bot_user(env): - """Create the ActiveBlue AI internal user so it appears in Discuss DM search.""" - if env['res.users'].search([('login', '=', 'activeblue_ai_bot')]): - return - user = env['res.users'].create({ - 'name': 'ActiveBlue AI', - 'login': 'activeblue_ai_bot', - 'groups_id': [(6, 0, [env.ref('base.group_user').id])], - 'share': False, - 'active': True, - }) - env['ir.model.data'].create({ - 'module': 'activeblue_ai', - 'name': 'partner_activeblue_ai', - 'model': 'res.partner', - 'res_id': user.partner_id.id, - 'noupdate': True, - }) - _logger.info('Created ActiveBlue AI bot user id=%d', user.id) + """Create the ActiveBlue AI internal user so it appears in Discuss DM search. + + Skips invitation email (no_reset_password) and marks the user as already + logged-in (res_users_log row) so it shows as Confirmed instead of Pending. + Also ensures the external ID exists so `env.ref('activeblue_ai.partner_activeblue_ai')` + resolves in the discuss.channel message override. + """ + User = env['res.users'].with_context(no_reset_password=True) + user = User.search([('login', 'in', ('activeblue_ai_bot', 'activeblue_ai_bot@local'))], limit=1) + if not user: + user = User.create({ + 'name': 'ActiveBlue AI', + 'login': 'activeblue_ai_bot', + 'groups_id': [(6, 0, [env.ref('base.group_user').id])], + 'share': False, + 'active': True, + }) + _logger.info('Created ActiveBlue AI bot user id=%d', user.id) + + # Ensure external ID -> partner mapping (needed by ab_ai_mail.py override) + imd = env['ir.model.data'] + existing = imd.search([ + ('module', '=', 'activeblue_ai'), + ('name', '=', 'partner_activeblue_ai'), + ], limit=1) + if existing: + existing.write({'model': 'res.partner', 'res_id': user.partner_id.id}) + else: + imd.create({ + 'module': 'activeblue_ai', + 'name': 'partner_activeblue_ai', + 'model': 'res.partner', + 'res_id': user.partner_id.id, + 'noupdate': True, + }) + + # Clear "Pending Invitations" state by writing a res_users_log row. + # In Odoo 18 the user state is computed from the existence of a log entry. + env.cr.execute( + "SELECT 1 FROM res_users_log WHERE create_uid = %s LIMIT 1", + (user.id,), + ) + if not env.cr.fetchone(): + env.cr.execute( + "INSERT INTO res_users_log (create_uid, create_date, write_uid, write_date) " + "VALUES (%s, NOW(), %s, NOW())", + (user.id, user.id), + ) + _logger.info('Marked ActiveBlue AI bot user id=%d as confirmed', user.id)