arm-core/api/tests/test_intercompany_matrix_golden.py
2026-10-16 13:19:49 +03:00

101 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Точные пары «Русского бисквита» на 30.09.2024 из ОСВ и ручного эталона.
Решение владельца 08.10.2026: общий итог элиминации с книгой не сравниваем —
аналитик снимает полную сумму каждой стороны, система использует минимум пары.
Здесь явно выбраны только точные встречные строки. Для 62.01 это производство
молочной булочки (строка 21); аренда (строка 17) в эту пару не входит.
Тест проверяет расчёт выбранных пар, а не автоматический подбор строк из всей ОСВ.
"""
import json
import uuid
from decimal import ROUND_HALF_UP, Decimal
from pathlib import Path
from types import SimpleNamespace
import pytest
from openpyxl import load_workbook
from src.schemas.consolidations import IntercompanyMatrixCompanyOut
from src.services.intercompany_matrix import MatrixSelection, calculate_matrix
pytestmark = pytest.mark.fixtures
GOLDEN = Path("golden/expected_osv_parse")
RB = uuid.UUID("11111111-1111-1111-1111-111111111111")
BAKERY = uuid.UUID("22222222-2222-2222-2222-222222222222")
def _source(fixtures_dir: Path, folder: str, account: str, number: int) -> dict:
matches = [
row
for path in sorted((fixtures_dir / GOLDEN / folder / "2024-Q3").glob("*.json"))
for document in json.loads(path.read_text("utf-8"))["documents"]
if document["document_type"] == "OSV" and document["header"]["account_code_raw"] == account
for row in document["rows"]
if row["row_number"] == number and row["group_type"] == "COUNTERPARTY" and row["data_type"] == "BU"
]
assert len(matches) == 1, (folder, account, number)
return matches[0]
@pytest.mark.parametrize(
("debit_root", "debit_row", "credit_root", "credit_row", "amount", "golden_cells"),
[
("62", 21, "60", 409, "106311116.46", ("F51",)),
# F50 содержит 42 млн основного долга + 350 тыс. процентов; J29 — основной долг.
("76", 20, "66", 28, "350000.00", ("F50", "J29")),
],
)
def test_exact_pairs_against_russian_biscuit_golden( # noqa: PLR0913 - описание пары и ячеек эталона
fixtures_dir: Path,
*,
debit_root: str,
debit_row: int,
credit_root: str,
credit_row: int,
amount: str,
golden_cells: tuple[str, ...],
) -> None:
debit = _source(fixtures_dir, "schastl", debit_root, debit_row)
credit = _source(fixtures_dir, "rb", credit_root, credit_row)
assert debit["counterparty_inn"] == "3528052718"
assert "СЧАСТЛИВОЧНАЯ" in credit["counterparty_name"]
debit_account, credit_account = uuid.uuid4(), uuid.uuid4()
rows = [
SimpleNamespace(
legal_entity_id=owner,
counterparty_id=counterparty,
account_id=account_id,
closing_debit=Decimal(source["closing_debit"] or "0"),
closing_credit=Decimal(source["closing_credit"] or "0"),
entry_ids=(uuid.uuid4(),),
)
for owner, counterparty, account_id, source in (
(BAKERY, RB, debit_account, debit),
(RB, BAKERY, credit_account, credit),
)
]
result = calculate_matrix(
rows,
[
IntercompanyMatrixCompanyOut(id=BAKERY, name="Пекарня Счастливочная"),
IntercompanyMatrixCompanyOut(id=RB, name="Русский бисквит"),
],
MatrixSelection(frozenset({debit_account}), frozenset({credit_account}), "closing"),
)
cell = result.cells[0]
assert cell.amount_a == cell.amount_b == Decimal(amount)
assert cell.variance_amount == cell.variance_percent == Decimal(0)
assert cell.one_sided is False and cell.exceeds_threshold is False
with (fixtures_dir / "golden/Консолидация_Группа РБ.xlsx").open("rb") as source:
workbook = load_workbook(source, read_only=True, data_only=True)
try:
sheet = workbook["01.10.2024"]
expected = Decimal(str(sheet[golden_cells[0]].value))
for address in golden_cells[1:]:
expected -= Decimal(str(sheet[address].value))
finally:
workbook.close()
# В книге тысячи рублей с округлением до целого; входные ОСВ содержат рубли и копейки.
assert (cell.amount_a / 1000).quantize(Decimal("1"), rounding=ROUND_HALF_UP) == expected