87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
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"}
|