Files
nifodea/infrastructure/cli/commands/forecast.py
T
oqyude b6b64a9878 T6: Decompose CLI — main.py → 9 command files, config.py → config_cmd.py
Split infrastructure/cli/:
- main.py (330 LOC) → 9 files in infrastructure/cli/commands/:
  * init.py, forecast.py, scenario.py, whatif.py, compare.py
  * import_xlsx.py, export_xlsx.py, analyze.py, info.py
- config.py (428 LOC) → commands/config_cmd.py (15 sub-commands)
- main.py → app.py (entry point: registers all commands)
- New: paths.py (MODEL_PATH, DATA_DIR)
- New: services.py (composition root + helpers: load_model, save_model,
  build_services, resolve_currency, convert_value, fmt_amount)
- cli/__init__.py (empty) удалён

Each command module: <100 LOC.
pyproject.toml: cf = infrastructure.cli.app:app
tests/test_cli.py: import обновлён на infrastructure.cli.app

CLI behavior идентично, все команды работают.
Tests: 67/67 pass.
2026-10-08 16:56:49 +03:00

57 lines
2.4 KiB
Python

"""cf forecast — прогноз денежных потоков."""
import typer
from rich.table import Table
from infrastructure.cli.i18n import t
from infrastructure.cli.services import (
build_services,
console,
convert_value,
fmt_amount,
load_model,
resolve_currency,
)
app = typer.Typer()
CURRENCY_OPTION = typer.Option(None, "--currency", "-c", help=t("cmd.forecast.opt.currency"))
@app.command()
def forecast(
months: int = typer.Option(12, "--months", "-m", help=t("cmd.forecast.opt.months")),
currency: str | None = CURRENCY_OPTION,
) -> None:
"""Запустить прогноз денежных потоков"""
model = load_model()
target_curr, symbol = resolve_currency(model, currency)
forecast_service, _, _, converter = build_services(model)
base_curr = model.base_currency
results = forecast_service.forecast_cashflow(months)
summary = forecast_service.summary(months)
if results:
table = Table(title=t("cmd.forecast.title", months=months, currency=target_curr))
table.add_column(t("cmd.forecast.col.account"), style="cyan")
table.add_column(t("cmd.forecast.col.month"), style="white")
table.add_column(t("cmd.forecast.col.balance"), justify="right", style="green")
table.add_column(t("cmd.forecast.col.income"), justify="right")
table.add_column(t("cmd.forecast.col.expenses"), justify="right")
for r in results:
table.add_row(
r["account"], str(r["month"]),
fmt_amount(convert_value(converter, r["balance"], base_curr, target_curr), target_curr, symbol),
fmt_amount(convert_value(converter, r["income"], base_curr, target_curr), target_curr, symbol),
fmt_amount(convert_value(converter, r["expenses"], base_curr, target_curr), target_curr, symbol),
)
console.print(table)
cb = convert_value(converter, summary["total_balance"], base_curr, target_curr)
ci = convert_value(converter, summary["total_income"], base_curr, target_curr)
ce = convert_value(converter, summary["total_expenses"], base_curr, target_curr)
console.print(t("cmd.forecast.total",
balance=fmt_amount(cb, target_curr, symbol),
income=fmt_amount(ci, target_curr, symbol),
expenses=fmt_amount(ce, target_curr, symbol)))