arm-core/api/tests/test_goodwill_domain.py
Andrey Epifancev a086c39a78 Гудвилл: доля до двух знаков, итоги по ГО и УК с бэка
participation() — единственное место формулы доли участия; totals с УК, group_totals
по ГО, GoodwillTableOut.groups; экспорт берёт «Всего» и «Итого по листу» из ответа таблицы;
доля 0–100 не больше двух знаков (DOC-259025 §5.2), ответ — два знака.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:22:26 +04:00

92 lines
4.5 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.

"""Расчёт и жизненный цикл на реальной сумме вложений Приманыческого."""
from decimal import Decimal
from pathlib import Path
from uuid import UUID
import pytest
from src.domain.goodwill import Decision, Investment, build, group_totals, participation, totals
from tests.test_goodwill_golden import investment_rows
pytestmark = pytest.mark.fixtures
A, B, C = (UUID(int=i) for i in (1, 2, 3))
def test_calculation_and_lifecycle(fixtures_dir: Path) -> None:
fv = Decimal(investment_rows(fixtures_dir)[0]["closing_debit"])
source = [Investment(A, B, fv)]
rows = build(source, {}, {B: Decimal("100000.00")})
assert rows[0].goodwill_amount is None
saved = {(A, B): Decision(Decimal("12.3456"), True, "Обоснование")}
row = build(source, saved, {B: Decimal("100000.00")})[0]
assert row.participation_amount == Decimal("12345.60")
assert row.goodwill_amount == fv - Decimal("12345.60")
gone = build([], saved, {})[0]
assert not gone.has_investments and gone.goodwill_amount is None
assert gone.financial_investment_amount is None
assert gone.decision == saved[A, B]
assert totals([gone], True)["financial_investment_amount"] == 0
assert build(source, saved, {B: Decimal("100000.00")})[0] == row
def test_zero_missing_capital_and_warning(fixtures_dir: Path) -> None:
fv = Decimal(investment_rows(fixtures_dir)[0]["closing_debit"])
source = [Investment(A, B, fv), Investment(C, B, fv)]
saved = {(A, B): Decision(Decimal("70"), True, "A"), (C, B): Decision(Decimal("40"), True, "C")}
rows = build(source, saved, {B: Decimal("0")})
assert all(r.participation_amount == 0 and r.goodwill_amount == fv for r in rows)
assert all("OWNERSHIP_TOTAL_EXCEEDED" in r.warnings for r in rows)
assert totals(rows, False)["goodwill_in_kfo_amount"] == 0
assert all(r.goodwill_amount is None for r in build(source, saved, {}))
def test_rounding_and_unselected(fixtures_dir: Path) -> None:
fv = Decimal(investment_rows(fixtures_dir)[0]["closing_debit"])
source = [Investment(A, B, fv)]
row = build(source, {(A, B): Decision(Decimal("0.0001"), False, None)}, {B: Decimal("5000")})[0]
assert row.participation_amount is None
selected = build(source, {(A, B): Decision(Decimal("0.0001"), True, "Подтверждено")}, {B: Decimal("5000")})[0]
assert selected.participation_amount == Decimal("0.01")
assert totals([row], True)["goodwill_amount"] == 0
assert totals([row], True)["financial_investment_amount"] == fv
def test_participation_rounds_half_up() -> None:
assert participation(Decimal("371.17"), Decimal("99.99")) == Decimal("371.13")
assert participation(Decimal("0.05"), Decimal("50")) == Decimal("0.03")
assert participation(Decimal("100000"), Decimal("0")) == Decimal("0.00")
def test_doc_example_totals() -> None:
"""DOC-259025 §11.1: Альфа → Бета (+100 000), Гамма (−30 000), Дельта без доли; плюс пара «Нет вложений»."""
alpha, beta, gamma, delta, gone = (UUID(int=i) for i in (10, 11, 12, 13, 14))
source = [
Investment(alpha, beta, Decimal("180000.00")),
Investment(alpha, gamma, Decimal("50000.00")),
Investment(alpha, delta, Decimal("60000.00")),
]
saved = {
(alpha, beta): Decision(Decimal("80"), True, "Устав"),
(alpha, gamma): Decision(Decimal("80"), True, "Устав"),
(alpha, gone): Decision(Decimal("50"), True, "Было"),
}
capital = {beta: Decimal("100000.00"), gamma: Decimal("100000.00"), delta: Decimal("60000.00")}
rows = {r.subsidiary_id: r for r in build(source, saved, capital)}
assert rows[beta].participation_amount == Decimal("80000.00")
assert rows[beta].goodwill_amount == Decimal("100000.00")
assert rows[gamma].participation_amount == Decimal("80000.00")
assert rows[gamma].goodwill_amount == Decimal("-30000.00")
assert rows[delta].participation_amount is None and rows[delta].goodwill_amount is None
assert not rows[gone].has_investments
expected = {
"financial_investment_amount": Decimal("290000.00"),
"charter_capital_amount": Decimal("260000.00"),
"participation_amount": Decimal("160000.00"),
"goodwill_amount": Decimal("70000.00"),
"goodwill_in_kfo_amount": Decimal("100000.00"),
}
assert totals(list(rows.values()), True) == expected
assert totals(list(rows.values()), False)["goodwill_in_kfo_amount"] == 0
assert group_totals(list(rows.values()), True) == {alpha: expected}