import logging import base64 _logger = logging.getLogger(__name__) def _get_report(env, ref_id): try: return env.ref(ref_id) except Exception: return None def _run_report(env, report_ref, params): report = _get_report(env, report_ref) if not report: return {'error': f'Report {report_ref} not found'} date_opts = {} if params.get('date_from'): date_opts['date_from'] = params['date_from'] if params.get('date_to'): date_opts['date_to'] = params['date_to'] options = report.get_options({'date': date_opts} if date_opts else {}) lines = report._get_lines(options) return { 'report_name': report.name, 'lines': [{ 'name': l.get('name', ''), 'level': l.get('level', 0), 'columns': [c.get('no_format', c.get('name', '')) for c in l.get('columns', [])], } for l in lines[:100]], } def get_profit_loss(env, params): return _run_report(env, 'account_reports.profit_and_loss', params) def get_balance_sheet(env, params): return _run_report(env, 'account_reports.balance_sheet', params) def get_trial_balance(env, params): return _run_report(env, 'account_reports.trial_balance_report', params) def get_cash_flow(env, params): return _run_report(env, 'account_reports.cash_flow_statement', params) def compare_periods(env, params): report_ref = params.get('report_ref', 'account_reports.profit_and_loss') report = _get_report(env, report_ref) if not report: return {'error': f'Report {report_ref} not found'} period1 = _run_report(env, report_ref, { 'date_from': params.get('period1_from'), 'date_to': params.get('period1_to'), }) period2 = _run_report(env, report_ref, { 'date_from': params.get('period2_from'), 'date_to': params.get('period2_to'), }) return {'period_1': period1, 'period_2': period2} def answer_financial_question(env, params): question = params.get('question', '') sql_query = params.get('sql_query') if sql_query: return {'error': 'Direct SQL not permitted. Use report tools instead.'} return {'status': 'info', 'message': f'Use specific report tools to answer: {question}'} def export_report(env, params): report_ref = params.get('report_ref', 'account_reports.profit_and_loss') fmt = params.get('format', 'pdf') report = _get_report(env, report_ref) if not report: return {'error': f'Report {report_ref} not found'} date_opts = {} if params.get('date_from'): date_opts['date_from'] = params['date_from'] if params.get('date_to'): date_opts['date_to'] = params['date_to'] options = report.get_options({'date': date_opts} if date_opts else {}) try: if fmt == 'xlsx': result = report.dispatch_report_action(options, 'export_to_xlsx') else: result = report.dispatch_report_action(options, 'export_to_pdf') if isinstance(result, dict) and result.get('file_content'): return { 'file_name': result.get('file_name', f'report.{fmt}'), 'file_type': result.get('file_type', fmt), 'file_content_b64': base64.b64encode(result['file_content']).decode(), } return { 'status': 'generated', 'message': f'Report exported as {fmt}. Use the Odoo UI to download.', } except Exception as e: return {'error': f'Export failed: {str(e)}'} TOOLS = { 'get_profit_loss': get_profit_loss, 'get_balance_sheet': get_balance_sheet, 'get_trial_balance': get_trial_balance, 'get_cash_flow': get_cash_flow, 'compare_periods': compare_periods, 'answer_financial_question': answer_financial_question, 'export_report': export_report, }