import os import shutil import subprocess import pytest from openpyxl import load_workbook from finance.exporting import build_formula_workbook pytestmark = pytest.mark.django_db def _recalculate(executable, source, output, profile): result = subprocess.run( [ executable, "--headless", f"-env:UserInstallation={profile.as_uri()}", "--convert-to", "xlsx", "--outdir", str(output), str(source), ], capture_output=True, text=True, timeout=120, check=False, ) assert result.returncode == 0, result.stderr or result.stdout recalculated = output / source.name assert recalculated.is_file(), result.stderr or result.stdout return recalculated def test_direct_and_lookup_gross_recalculate_and_roll_up(workspace, tmp_path): executable = os.environ.get("SOFFICE_BIN") or shutil.which("soffice") if not executable: pytest.skip("set SOFFICE_BIN to run the LibreOffice recalculation check") ds, member, *_ = workspace ds.mapping = {**ds.mapping, "margin_rates": {"医疗服务": "0.25"}} ds.save(update_fields=["mapping"]) lookup_fact = ds.facts.get(period="2026-08", source_row=5) lookup_fact.raw[5] = "" lookup_fact.save(update_fields=["raw"]) source_dir, output_dir = tmp_path / "source", tmp_path / "recalculated" source_dir.mkdir() output_dir.mkdir() workbook_path = source_dir / "gross-sources.xlsx" with workbook_path.open("wb") as workbook_file: build_formula_workbook( ds, member, {"start": "2026-08", "end": "2026-08", "comparison": "yoy", "group": "department"}, workbook_file, ) recalculated = _recalculate(executable, workbook_path, output_dir, tmp_path / "lo-profile-gross") formulas = load_workbook(recalculated, data_only=False) values = load_workbook(recalculated, data_only=True) details = values["计算明细"] assert details["I4"].value == "direct" assert details["I5"].value == "lookup" assert details["N4"].value == pytest.approx(50) assert details["N5"].value == pytest.approx(5) summary_formula = formulas["分析汇总"] summary_values = values["分析汇总"] row = next( row for row in range(6, summary_formula.max_row + 1) if summary_formula.cell(row, 1).value == "毛利贡献" ) assert summary_formula.cell(row, 3).value.startswith("=") assert summary_values.cell(row, 3).value == pytest.approx(55) errors = { cell.value for sheet in values for row_cells in sheet.iter_rows() for cell in row_cells if cell.data_type == "e" } assert errors <= {"#N/A"}