# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) import logging from datetime import datetime, timedelta, date from odoo import http, _ from odoo.http import request _logger = logging.getLogger(__name__) class FusionClockPortalAI(http.Controller): def _get_employee(self): return request.env['hr.employee'].sudo().search([ ('user_id', '=', request.env.uid), ], limit=1) @http.route('/fusion_clock_ai/employee_chat', type='json', auth='user') def employee_chat(self, message, conversation_id=None): ICP = request.env['ir.config_parameter'].sudo() if ICP.get_param('fusion_clock_ai.enable_employee_chat', 'True') != 'True': return {'error': 'AI Assistant is currently disabled.'} employee = self._get_employee() if not employee: return {'error': 'No employee record found.'} AI = request.env['fusion.clock.ai.service'].sudo() context_data = AI._build_employee_context( employee, date.today() - timedelta(days=30), date.today(), ) Conversation = request.env['fusion.clock.ai.conversation'].sudo() if conversation_id: conv = Conversation.browse(int(conversation_id)) if not conv.exists() or conv.user_id.id != request.env.uid: conv = Conversation.create({ 'user_id': request.env.uid, 'conversation_type': 'employee_chat', }) else: conv = Conversation.create({ 'user_id': request.env.uid, 'conversation_type': 'employee_chat', }) Message = request.env['fusion.clock.ai.message'].sudo() Message.create({ 'conversation_id': conv.id, 'role': 'user', 'content': message, }) system_prompt = AI._get_system_prompt('employee_chat') messages = [ {'role': 'system', 'content': f"{system_prompt}\n\n--- YOUR ATTENDANCE DATA ---\n{context_data}"}, ] for msg in conv.message_ids: messages.append({'role': msg.role, 'content': msg.content}) try: response = AI.chat_completion(messages, feature='employee_chat') except Exception as e: return {'error': str(e)} Message.create({ 'conversation_id': conv.id, 'role': 'assistant', 'content': response, }) return { 'response': response, 'conversation_id': conv.id, } @http.route('/fusion_clock_ai/polish_reason', type='json', auth='user') def polish_reason(self, rough_text): AI = request.env['fusion.clock.ai.service'].sudo() system_prompt = AI._get_system_prompt('leave_reason_writer') try: response = AI.chat_completion( [ {'role': 'system', 'content': system_prompt}, {'role': 'user', 'content': rough_text}, ], feature='leave_reason_writer', ) except Exception as e: return {'error': str(e)} return {'polished': response} @http.route('/fusion_clock_ai/my_coach_tip', type='json', auth='user') def my_coach_tip(self): employee = self._get_employee() if not employee: return {'error': 'No employee record found.'} AI = request.env['fusion.clock.ai.service'].sudo() context_data = AI._build_employee_context( employee, date.today() - timedelta(days=14), date.today(), ) system_prompt = AI._get_system_prompt('attendance_coach') try: response = AI.chat_completion( [ {'role': 'system', 'content': system_prompt}, {'role': 'user', 'content': context_data}, ], feature='attendance_coach', ) except Exception as e: return {'error': str(e)} return {'tip': response}