118 lines
3.8 KiB
Python
118 lines
3.8 KiB
Python
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,
|
|
}
|