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.
42 lines
1.9 KiB
Python
42 lines
1.9 KiB
Python
"""cf whatif — what-if анализ с произвольными множителями."""
|
|
import typer
|
|
|
|
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 whatif(
|
|
income: float = typer.Option(1.0, "--income", "-i", help=t("cmd.whatif.opt.income")),
|
|
expense: float = typer.Option(1.0, "--expense", "-e", help=t("cmd.whatif.opt.expense")),
|
|
growth: float = typer.Option(1.0, "--growth", "-g", help=t("cmd.whatif.opt.growth")),
|
|
months: int = typer.Option(12, "--months", "-m", help=t("cmd.whatif.opt.months")),
|
|
currency: str | None = CURRENCY_OPTION,
|
|
) -> None:
|
|
"""What-if анализ с произвольными множителями"""
|
|
model = load_model()
|
|
target_curr, symbol = resolve_currency(model, currency)
|
|
_, scenario_service, _, converter = build_services(model)
|
|
base_curr = model.base_currency
|
|
result = scenario_service.what_if(income, expense, growth, months)
|
|
|
|
balance = convert_value(converter, result["total_balance"], base_curr, target_curr)
|
|
income_v = convert_value(converter, result["total_income"], base_curr, target_curr)
|
|
expenses = convert_value(converter, result["total_expenses"], base_curr, target_curr)
|
|
console.print(f"[bold]{t('cmd.whatif.title')}[/bold]")
|
|
console.print(t("cmd.whatif.params", income=income, expense=expense, growth=growth))
|
|
console.print(f"{t('cmd.scenario.label.balance')}: {fmt_amount(balance, target_curr, symbol)}")
|
|
console.print(f"{t('cmd.scenario.label.income')}: {fmt_amount(income_v, target_curr, symbol)}")
|
|
console.print(f"{t('cmd.scenario.label.expenses')}: {fmt_amount(expenses, target_curr, symbol)}")
|