feat(fusion_accounting_reports): XLSX export wizard

Adds a TransientModel wizard fusion.xlsx.export.wizard that lets users
pick a report type, date range, and comparison mode, then runs the
engine and produces an XLSX via xlsxwriter (in-memory).

The wizard exposes a download field that becomes available after export
finishes. Works on P&L, Balance Sheet, Trial Balance, and General Ledger.
Comparison columns are written when the engine returns a comparison_period
in the result.

Also wires the controller's /fusion/reports/export_xlsx endpoint to drive
the wizard and return base64-encoded XLSX bytes (replaces the not_implemented
placeholder).

Tests: 2 new (test_xlsx_export.py) + 1 controller test updated. Manifest
declares xlsxwriter as an external_dependency.

Made-with: Cursor
This commit is contained in:
gsinghpal
2026-04-19 16:16:36 -04:00
parent 23b988c401
commit 7d7bd93345
10 changed files with 202 additions and 5 deletions

View File

@@ -19,3 +19,4 @@ from . import test_bs_tb_integration
from . import test_account_balance_mv
from . import test_cron
from . import test_pdf_export
from . import test_xlsx_export

View File

@@ -111,10 +111,16 @@ class TestReportsController(HttpCase):
self.assertIn('pdf_base64', result)
self.assertTrue(result.get('filename', '').endswith('.pdf'))
def test_export_xlsx_placeholder(self):
def test_export_xlsx_returns_xlsx(self):
try:
import xlsxwriter # noqa: F401
except ImportError:
self.skipTest("xlsxwriter not installed")
result = self._jsonrpc('export_xlsx', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
})
self.assertEqual(result.get('status'), 'not_implemented')
self.assertEqual(result.get('status'), 'ok')
self.assertTrue(result.get('xlsx_base64'))
self.assertTrue(result.get('filename', '').endswith('.xlsx'))

View File

@@ -0,0 +1,36 @@
"""Tests for XLSX export wizard."""
from datetime import date
from odoo.tests.common import TransactionCase, tagged
@tagged('post_install', '-at_install')
class TestXlsxExport(TransactionCase):
def test_export_pnl_produces_xlsx(self):
try:
import xlsxwriter # noqa: F401
except ImportError:
self.skipTest("xlsxwriter not installed")
wizard = self.env['fusion.xlsx.export.wizard'].create({
'report_type': 'pnl',
'date_from': date(2026, 1, 1),
'date_to': date(2026, 12, 31),
})
wizard.action_export()
self.assertEqual(wizard.state, 'done')
self.assertTrue(wizard.xlsx_file)
self.assertTrue(wizard.xlsx_filename.endswith('.xlsx'))
def test_export_balance_sheet(self):
try:
import xlsxwriter # noqa: F401
except ImportError:
self.skipTest("xlsxwriter not installed")
wizard = self.env['fusion.xlsx.export.wizard'].create({
'report_type': 'balance_sheet',
'date_from': date(2026, 1, 1),
'date_to': date(2026, 12, 31),
})
wizard.action_export()
self.assertEqual(wizard.state, 'done')