participation() — единственное место формулы доли участия; totals с УК, group_totals по ГО, GoodwillTableOut.groups; экспорт берёт «Всего» и «Итого по листу» из ответа таблицы; доля 0–100 не больше двух знаков (DOC-259025 §5.2), ответ — два знака. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
4.5 KiB
Python
92 lines
4.5 KiB
Python
"""Расчёт и жизненный цикл на реальной сумме вложений Приманыческого."""
|
||
|
||
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}
|