from __future__ import annotations import logging from ..tools.odoo_client import OdooClient logger = logging.getLogger(__name__) class EmployeesTools: def __init__(self, odoo: OdooClient): self._o = odoo async def get_employees(self, department_id: int = None, active: bool = True, limit: int = 100) -> list: domain = [('active', '=', active)] if department_id: domain.append(('department_id', '=', department_id)) fields = ['name', 'department_id', 'job_id', 'job_title', 'work_email', 'coach_id', 'parent_id', 'employee_type'] return await self._o.search_read('hr.employee', domain, fields, limit=limit) async def get_employee_profile(self, employee_id: int) -> dict: employees = await self._o.search_read( 'hr.employee', [('id', '=', employee_id)], ['name', 'department_id', 'job_id', 'job_title', 'work_email', 'coach_id', 'parent_id', 'employee_type', 'study_field', 'study_school'], limit=1, ) return employees[0] if employees else {} async def get_leaves(self, employee_id: int = None, state: str = None, date_from: str = None, limit: int = 50) -> list: domain = [] if employee_id: domain.append(('employee_id', '=', employee_id)) if state: domain.append(('state', '=', state)) if date_from: domain.append(('date_from', '>=', date_from)) fields = ['name', 'employee_id', 'holiday_status_id', 'date_from', 'date_to', 'number_of_days', 'state'] return await self._o.search_read('hr.leave', domain, fields, limit=limit) async def get_contracts(self, employee_id: int = None, state: str = 'open', limit: int = 50) -> list: domain = [('state', '=', state)] if employee_id: domain.append(('employee_id', '=', employee_id)) fields = ['name', 'employee_id', 'wage', 'date_start', 'date_end', 'state', 'structure_type_id'] return await self._o.search_read('hr.contract', domain, fields, limit=limit) async def get_attendance_summary(self, employee_id: int, date_from: str, date_to: str) -> dict: domain = [ ('employee_id', '=', employee_id), ('check_in', '>=', date_from), ('check_in', '<=', date_to), ] records = await self._o.search_read('hr.attendance', domain, ['worked_hours', 'check_in'], limit=200) total_hours = sum(r.get('worked_hours', 0) for r in records) days_present = len(set(r['check_in'][:10] for r in records if r.get('check_in'))) return { 'employee_id': employee_id, 'period_from': date_from, 'period_to': date_to, 'total_hours': round(total_hours, 2), 'days_present': days_present, 'attendance_records': len(records), } async def get_department_summary(self, department_id: int) -> dict: employees = await self.get_employees(department_id=department_id) active_contracts = await self.get_contracts(state='open') dept_contracts = [c for c in active_contracts if any(e['id'] == (c['employee_id'][0] if isinstance(c['employee_id'], list) else c['employee_id']) for e in employees)] return { 'department_id': department_id, 'headcount': len(employees), 'active_contracts': len(dept_contracts), 'avg_wage': sum(c.get('wage', 0) for c in dept_contracts) / max(len(dept_contracts), 1), } async def flag_for_review(self, model: str, record_id: int, reason: str, severity: str = 'medium') -> bool: msg = f'[AI FLAG - {severity.upper()}] {reason}' await self._o.call(model, 'message_post', [[record_id]], {'body': msg, 'message_type': 'comment'}) return True async def post_chatter_note(self, model: str, record_id: int, note: str) -> bool: await self._o.call(model, 'message_post', [[record_id]], {'body': note, 'message_type': 'comment'}) return True