Files
Odoo-Modules/fusion_accounting_reports/reports/report_pdf.py
gsinghpal 23b988c401 feat(fusion_accounting_reports): PDF export with QWeb template
Adds an AbstractModel report (report_pdf.py) and a single multi-purpose
QWeb template (report_pdf_template.xml) that renders P&L, Balance Sheet,
Trial Balance, and General Ledger results from the engine.

Wires the controller's /fusion/reports/export_pdf endpoint to actually
return base64-encoded PDF bytes via _render_qweb_pdf. The template walks
the result['rows'] list and applies indentation/bold based on level and
is_subtotal flags, with optional comparison columns when present.

Tests: 2 new (test_pdf_export.py) + 1 controller test updated to assert
the real PDF response. Net 109 -> 111.

Made-with: Cursor
2026-04-19 16:13:22 -04:00

59 lines
2.4 KiB
Python

"""QWeb PDF report for fusion financial reports.
Wraps the engine's compute_* methods and feeds the result into a
single multi-purpose template that handles all 4 report types."""
from datetime import datetime
from odoo import api, models
from ..services.date_periods import Period
class FusionReportPdf(models.AbstractModel):
_name = "report.fusion_accounting_reports.report_pdf_template"
_description = "Fusion Financial Report PDF"
@api.model
def _get_report_values(self, docids, data=None):
"""data is expected to be {report_type, date_from, date_to, comparison, company_id}."""
data = data or {}
report_type = data.get('report_type', 'pnl')
company_id = data.get('company_id') or self.env.company.id
date_from = data.get('date_from')
date_to = data.get('date_to')
comparison = data.get('comparison', 'none')
if isinstance(date_from, str):
date_from = datetime.strptime(date_from, '%Y-%m-%d').date()
if isinstance(date_to, str):
date_to = datetime.strptime(date_to, '%Y-%m-%d').date()
engine = self.env['fusion.report.engine']
if report_type == 'pnl':
period = Period(date_from, date_to, f"{date_from} - {date_to}")
result = engine.compute_pnl(period, comparison=comparison, company_id=company_id)
elif report_type == 'balance_sheet':
result = engine.compute_balance_sheet(date_to, comparison=comparison, company_id=company_id)
elif report_type == 'trial_balance':
period = Period(date_from, date_to, f"{date_from} - {date_to}")
result = engine.compute_trial_balance(period, company_id=company_id)
elif report_type == 'general_ledger':
period = Period(date_from, date_to, f"{date_from} - {date_to}")
result = engine.compute_gl(period, company_id=company_id)
else:
result = {'rows': [], 'report_name': 'Unknown', 'period': {}}
company = self.env['res.company'].browse(company_id)
return {
'doc_ids': docids,
'doc_model': 'fusion.report',
'docs': self.env['fusion.report'].browse(docids) if docids else
self.env['fusion.report'].search([('report_type', '=', report_type)], limit=1),
'data': data,
'result': result,
'company_id': company,
'company': company,
'res_company': company,
}