📊

Калькулятор с русской локалью

Паттерны Python-кода для точных финансовых расчётов с форматированием по ГОСТ Р 54521-2011. Расчёт пеней, неустоек, процентов по ст. 395 ГК РФ, НДС, ключевой ставки ЦБ.

Системный промпт

Калькулятор с русской локалью

Этот skill содержит паттерны Python-кода для финансовых расчётов в песочнице.


Разрешённые библиотеки

decimal    — точная арифметика денежных сумм
math       — математические функции
datetime   — работа с датами и периодами
statistics — статистические расчёты

БЛОК 1: Базовая арифметика

Паттерн: Инициализация Decimal

from decimal import Decimal, ROUND_HALF_UP

amount = Decimal("1234567.89")
rate = Decimal("0.001")

Паттерн: Округление денежных сумм

from decimal import Decimal, ROUND_HALF_UP

def round_money(value: Decimal, places: int = 2) -> Decimal:
    quantize_str = "0." + "0" * places
    return value.quantize(Decimal(quantize_str), rounding=ROUND_HALF_UP)

total = Decimal("1234.5678")
result = round_money(total)

Паттерн: Процент от суммы

from decimal import Decimal, ROUND_HALF_UP

principal = Decimal("500000")
percent = Decimal("0.1")
result = (principal * percent / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

Паттерн: Деление с точностью

from decimal import Decimal, ROUND_HALF_UP, localcontext

with localcontext() as ctx:
    ctx.prec = 28
    numerator = Decimal("1000000")
    denominator = Decimal("365")
    daily = (numerator / denominator).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

БЛОК 2: Форматирование по ГОСТ

Паттерн: Форматирование рублей

from decimal import Decimal

def format_rub(value: Decimal) -> str:
    sign = "-" if value < 0 else ""
    abs_val = abs(value)
    int_part = int(abs_val)
    frac_part = abs_val - int_part

    int_str = ""
    s = str(int_part)
    for i, char in enumerate(reversed(s)):
        if i > 0 and i % 3 == 0:
            int_str = " " + int_str
        int_str = char + int_str

    frac_str = str(frac_part.quantize(Decimal("0.01")))[2:]
    return f"{sign}{int_str},{frac_str} \u20bd"

amount = Decimal("1234567.89")
formatted = format_rub(amount)

Паттерн: Форматирование процентов

from decimal import Decimal

def format_percent(value: Decimal) -> str:
    return f"{value.quantize(Decimal('0.01'))}%".replace(".", ",")

rate = Decimal("16.5")
formatted = format_percent(rate)

Паттерн: Сумма прописью (упрощённая)

from decimal import Decimal

def amount_words_simple(value: Decimal) -> str:
    int_part = int(value)
    frac_part = int((value - int_part) * 100)
    return f"{int_part} руб. {frac_part:02d} коп."

amount = Decimal("12345.67")
words = amount_words_simple(amount)

БЛОК 3: Финансовые формулы

Паттерн: Расчёт НДС

from decimal import Decimal, ROUND_HALF_UP

def calc_vat(amount: Decimal, rate: Decimal = Decimal("22")) -> dict:
    vat = (amount * rate / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    total = amount + vat
    return {"base": amount, "vat": vat, "total": total, "rate": rate}

result = calc_vat(Decimal("100000"))

Паттерн: Выделение НДС из суммы

from decimal import Decimal, ROUND_HALF_UP

def extract_vat(total: Decimal, rate: Decimal = Decimal("22")) -> dict:
    base = (total * Decimal("100") / (Decimal("100") + rate)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    vat = total - base
    return {"total": total, "base": base, "vat": vat, "rate": rate}

result = extract_vat(Decimal("122000"))

Паттерн: Неустойка по договору

from decimal import Decimal, ROUND_HALF_UP
from datetime import date

def calc_penalty(debt: Decimal, daily_rate: Decimal, start: date, end: date) -> dict:
    days = (end - start).days
    penalty = (debt * daily_rate / Decimal("100") * days).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    return {
        "debt": debt,
        "daily_rate": daily_rate,
        "days": days,
        "penalty": penalty,
        "formula": f"{debt} x {daily_rate}% x {days} дн."
    }

result = calc_penalty(
    debt=Decimal("500000"),
    daily_rate=Decimal("0.1"),
    start=date(2024, 1, 15),
    end=date(2024, 3, 15)
)

Паттерн: Проценты по ст. 395 ГК РФ

from decimal import Decimal, ROUND_HALF_UP
from datetime import date

def calc_395_interest(debt: Decimal, cbr_rate: Decimal, start: date, end: date) -> dict:
    days = (end - start).days
    interest = (debt * cbr_rate / Decimal("100") / Decimal("365") * days).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    return {
        "debt": debt,
        "cbr_rate": cbr_rate,
        "days": days,
        "interest": interest,
        "formula": f"{debt} x {cbr_rate}% / 365 x {days} дн."
    }

result = calc_395_interest(
    debt=Decimal("1000000"),
    cbr_rate=Decimal("16"),
    start=date(2024, 1, 1),
    end=date(2024, 3, 15)
)

Паттерн: Сложный процент

from decimal import Decimal, ROUND_HALF_UP

def compound_interest(principal: Decimal, annual_rate: Decimal, years: int, periods_per_year: int = 12) -> dict:
    r = annual_rate / Decimal("100") / Decimal(str(periods_per_year))
    n = years * periods_per_year

    multiplier = (Decimal("1") + r) ** n
    final = (principal * multiplier).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    interest = final - principal

    return {
        "principal": principal,
        "final": final,
        "interest": interest,
        "annual_rate": annual_rate,
        "years": years
    }

result = compound_interest(
    principal=Decimal("1000000"),
    annual_rate=Decimal("12"),
    years=2
)

Паттерн: Аннуитетный платёж

from decimal import Decimal, ROUND_HALF_UP

def annuity_payment(principal: Decimal, annual_rate: Decimal, months: int) -> dict:
    monthly_rate = annual_rate / Decimal("100") / Decimal("12")

    if monthly_rate == 0:
        payment = principal / Decimal(str(months))
    else:
        r = monthly_rate
        n = months
        payment = principal * r * ((1 + r) ** n) / (((1 + r) ** n) - 1)

    payment = payment.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    total = payment * months
    overpayment = total - principal

    return {
        "principal": principal,
        "monthly_payment": payment,
        "total": total,
        "overpayment": overpayment,
        "months": months
    }

result = annuity_payment(
    principal=Decimal("1000000"),
    annual_rate=Decimal("12"),
    months=24
)

БЛОК 4: Расчёты с датами

Паттерн: Дни между датами

from datetime import date

def days_between(start: date, end: date) -> int:
    return (end - start).days

days = days_between(date(2024, 1, 1), date(2024, 3, 15))

Паттерн: Добавление месяцев

from datetime import date
from dateutil.relativedelta import relativedelta

def add_months(start: date, months: int) -> date:
    return start + relativedelta(months=months)

new_date = add_months(date(2024, 1, 31), 1)

Паттерн: Рабочие дни (производственный календарь РФ)

import sys
sys.path.insert(0, "/tmp/scripts")
from scripts.production_calendar import is_business_day, add_business_days, count_business_days
from datetime import date

deadline = add_business_days(date(2025, 1, 15), 10)
bdays = count_business_days(date(2025, 2, 1), date(2025, 2, 28))
print(f"Дедлайн: {deadline}, рабочих дней в феврале: {bdays}")

Паттерн: Последний день месяца

from datetime import date
import calendar

def last_day_of_month(year: int, month: int) -> date:
    last_day = calendar.monthrange(year, month)[1]
    return date(year, month, last_day)

last = last_day_of_month(2024, 2)

Паттерн: Срок исковой давности

from datetime import date
from dateutil.relativedelta import relativedelta

def limitation_period(event_date: date, years: int = 3) -> dict:
    expires = event_date + relativedelta(years=years)
    today = date.today()
    days_left = (expires - today).days

    return {
        "event_date": event_date.isoformat(),
        "expires": expires.isoformat(),
        "days_left": max(0, days_left),
        "expired": today > expires
    }

result = limitation_period(date(2022, 6, 15))

БЛОК 5: Периоды ключевой ставки ЦБ

Паттерн: Расчёт с изменяющейся ставкой

from decimal import Decimal, ROUND_HALF_UP
from datetime import date

def calc_interest_periods(debt: Decimal, periods: list) -> dict:
    total_interest = Decimal("0")
    total_days = 0
    details = []

    for p in periods:
        start = date.fromisoformat(p["start"])
        end = date.fromisoformat(p["end"])
        rate = Decimal(str(p["rate"]))
        days = (end - start).days + 1

        interest = (debt * rate / Decimal("100") / Decimal("365") * days).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        total_interest += interest
        total_days += days

        details.append({
            "period": f"{p['start']} — {p['end']}",
            "days": days,
            "rate": float(rate),
            "interest": float(interest)
        })

    return {
        "debt": float(debt),
        "total_days": total_days,
        "total_interest": float(total_interest),
        "details": details
    }

result = calc_interest_periods(
    debt=Decimal("1000000"),
    periods=[
        {"start": "2024-01-01", "end": "2024-01-31", "rate": "16"},
        {"start": "2024-02-01", "end": "2024-02-29", "rate": "16"},
        {"start": "2024-03-01", "end": "2024-03-15", "rate": "16"}
    ]
)

БЛОК 6: Структура вывода

Паттерн: JSON-ответ калькулятора

import json
from decimal import Decimal

def calculator_response(result: Decimal, formula: str, inputs: dict) -> str:
    sign = "-" if result < 0 else ""
    abs_val = abs(result)
    int_part = int(abs_val)
    frac_part = abs_val - int_part

    int_str = ""
    s = str(int_part)
    for i, char in enumerate(reversed(s)):
        if i > 0 and i % 3 == 0:
            int_str = " " + int_str
        int_str = char + int_str

    frac_str = str(frac_part.quantize(Decimal("0.01")))[2:]
    formatted = f"{sign}{int_str},{frac_str} \u20bd"

    output = {
        "result": float(result),
        "formatted": formatted,
        "formula": formula,
        "inputs": inputs
    }
    return json.dumps(output, ensure_ascii=False, indent=2)

response = calculator_response(
    result=Decimal("30000.00"),
    formula="500 000 x 0,1% x 60 дн.",
    inputs={"debt": 500000, "rate": 0.1, "days": 60}
)
print(response)


БЛОК 7: Налоговые расчёты (ставки 2026)

Паттерн: УСН «Доходы» (6%)

from decimal import Decimal, ROUND_HALF_UP

def calc_usn_income(revenue: Decimal, insurance_paid: Decimal = Decimal("0"), employees: bool = False) -> dict:
    """
    УСН 6% (Доходы). Налог уменьшается на страховые взносы:
    - ИП без работников: до 100%
    - ИП/ООО с работниками: до 50%
    """
    tax_raw = (revenue * Decimal("6") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    if employees:
        max_deduction = (tax_raw * Decimal("0.5")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    else:
        max_deduction = tax_raw

    deduction = min(insurance_paid, max_deduction)
    tax_due = tax_raw - deduction

    return {
        "revenue": revenue,
        "tax_rate": "6%",
        "tax_raw": tax_raw,
        "insurance_deduction": deduction,
        "tax_due": tax_due,
        "effective_rate": (tax_due / revenue * Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if revenue else Decimal("0"),
    }

result = calc_usn_income(Decimal("5000000"), insurance_paid=Decimal("55766"), employees=False)

Паттерн: УСН «Доходы минус расходы» (15%)

from decimal import Decimal, ROUND_HALF_UP

def calc_usn_income_expense(revenue: Decimal, expenses: Decimal) -> dict:
    """
    УСН 15% (Доходы - расходы).
    Минимальный налог: 1% от доходов.
    """
    profit = revenue - expenses
    tax_15 = (profit * Decimal("15") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if profit > 0 else Decimal("0")
    tax_min = (revenue * Decimal("1") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    tax_due = max(tax_15, tax_min)
    is_minimum = tax_due == tax_min and tax_15 < tax_min

    return {
        "revenue": revenue,
        "expenses": expenses,
        "profit": profit,
        "tax_15": tax_15,
        "tax_min": tax_min,
        "tax_due": tax_due,
        "is_minimum_tax": is_minimum,
    }

result = calc_usn_income_expense(Decimal("10000000"), Decimal("9200000"))

Паттерн: ОСНО — комплексный расчёт (НДС + прибыль + НДФЛ дивидендов)

from decimal import Decimal, ROUND_HALF_UP

def calc_osno(revenue: Decimal, expenses: Decimal, dividends: Decimal = Decimal("0")) -> dict:
    """
    ОСНО 2026: НДС 22%, налог на прибыль 25%, НДФЛ с дивидендов.
    """
    # НДС
    vat_output = (revenue * Decimal("22") / Decimal("122")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    vat_input = (expenses * Decimal("22") / Decimal("122")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    vat_due = vat_output - vat_input

    # Прибыль (без НДС)
    revenue_net = revenue - vat_output
    expenses_net = expenses - vat_input
    profit = revenue_net - expenses_net
    profit_tax = (profit * Decimal("25") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if profit > 0 else Decimal("0")

    # НДФЛ с дивидендов (13%/15% с порогом 2,4 млн)
    ndfl_div = Decimal("0")
    if dividends > 0:
        if dividends <= Decimal("2400000"):
            ndfl_div = (dividends * Decimal("13") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        else:
            ndfl_div = (Decimal("2400000") * Decimal("13") / Decimal("100") + (dividends - Decimal("2400000")) * Decimal("15") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    total_taxes = vat_due + profit_tax + ndfl_div

    return {
        "revenue": revenue,
        "expenses": expenses,
        "vat_output": vat_output,
        "vat_input": vat_input,
        "vat_due": vat_due,
        "profit": profit,
        "profit_tax": profit_tax,
        "dividends": dividends,
        "ndfl_dividends": ndfl_div,
        "total_taxes": total_taxes,
    }

result = calc_osno(Decimal("12200000"), Decimal("7320000"), dividends=Decimal("3000000"))

Паттерн: НДФЛ — прогрессивная шкала 2026

from decimal import Decimal, ROUND_HALF_UP

def calc_ndfl_progressive(annual_income: Decimal) -> dict:
    """
    НДФЛ прогрессивная шкала 2026:
    до 2,4 млн — 13%, 2,4-5 млн — 15%, 5-20 млн — 18%,
    20-50 млн — 20%, свыше 50 млн — 22%.
    """
    brackets = [
        (Decimal("2400000"), Decimal("13")),
        (Decimal("5000000"), Decimal("15")),
        (Decimal("20000000"), Decimal("18")),
        (Decimal("50000000"), Decimal("20")),
        (None, Decimal("22")),
    ]

    remaining = annual_income
    total_tax = Decimal("0")
    prev_limit = Decimal("0")
    details = []

    for limit, rate in brackets:
        if remaining <= 0:
            break
        bracket_size = (limit - prev_limit) if limit else remaining
        taxable = min(remaining, bracket_size)
        tax = (taxable * rate / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        total_tax += tax
        details.append({"bracket": f"{prev_limit}-{limit or 'inf'}", "rate": f"{rate}%", "taxable": taxable, "tax": tax})
        remaining -= taxable
        prev_limit = limit if limit else prev_limit

    effective_rate = (total_tax / annual_income * Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if annual_income > 0 else Decimal("0")

    return {
        "annual_income": annual_income,
        "total_tax": total_tax,
        "effective_rate": effective_rate,
        "net_income": annual_income - total_tax,
        "details": details,
    }

result = calc_ndfl_progressive(Decimal("6000000"))

Паттерн: Патентная система налогообложения (ПСН)

from decimal import Decimal, ROUND_HALF_UP

def calc_patent(potential_income: Decimal, months: int = 12, insurance_paid: Decimal = Decimal("0"), employees: bool = False) -> dict:
    """
    Патент: 6% от потенциального дохода (устанавливается регионом).
    Уменьшается на страховые взносы (аналогично УСН Доходы).
    """
    annual_tax = (potential_income * Decimal("6") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    tax_raw = (annual_tax * Decimal(str(months)) / Decimal("12")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    if employees:
        max_deduction = (tax_raw * Decimal("0.5")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    else:
        max_deduction = tax_raw

    deduction = min(insurance_paid, max_deduction)
    tax_due = tax_raw - deduction

    return {
        "potential_income": potential_income,
        "months": months,
        "tax_raw": tax_raw,
        "insurance_deduction": deduction,
        "tax_due": tax_due,
    }

result = calc_patent(Decimal("1500000"), months=12, insurance_paid=Decimal("55766"))

Паттерн: Страховые взносы ИП за себя (2026)

from decimal import Decimal, ROUND_HALF_UP

def calc_ip_insurance(annual_income: Decimal, months: int = 12) -> dict:
    """
    Страховые взносы ИП за себя 2026:
    - Фиксированная часть (ОПС + ОМС): 55 766 руб. (за полный год)
    - Дополнительный 1% с доходов свыше 300 000 руб.
    - Максимум допвзносов: 300 888 руб. (8 x фикс.)
    """
    FIXED_ANNUAL = Decimal("55766")
    THRESHOLD = Decimal("300000")
    MAX_EXTRA = Decimal("300888")

    fixed = (FIXED_ANNUAL * Decimal(str(months)) / Decimal("12")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    if annual_income > THRESHOLD:
        extra = ((annual_income - THRESHOLD) * Decimal("1") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        extra = min(extra, MAX_EXTRA)
    else:
        extra = Decimal("0")

    total = fixed + extra

    return {
        "annual_income": annual_income,
        "months": months,
        "fixed_contributions": fixed,
        "extra_1_percent": extra,
        "total_contributions": total,
        "deadline_fixed": "31.12.2026",
        "deadline_extra": "01.07.2027",
    }

result = calc_ip_insurance(Decimal("5000000"))

Паттерн: Сравнение налоговых режимов

from decimal import Decimal, ROUND_HALF_UP

def compare_tax_regimes(revenue: Decimal, expenses: Decimal, potential_income_patent: Decimal = Decimal("0")) -> dict:
    """
    Сравнение УСН 6%, УСН 15%, ОСНО и патента для одинаковых входных данных.
    """
    ip_insurance = Decimal("55766")

    # УСН 6%
    usn6_tax = (revenue * Decimal("6") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    usn6_tax = max(Decimal("0"), usn6_tax - ip_insurance)

    # УСН 15%
    profit_usn = revenue - expenses
    usn15_tax = (profit_usn * Decimal("15") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if profit_usn > 0 else Decimal("0")
    usn15_min = (revenue * Decimal("1") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    usn15_tax = max(usn15_tax, usn15_min)

    # ОСНО (упрощённо)
    vat_due = ((revenue - expenses) * Decimal("22") / Decimal("122")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    profit_net = (revenue - expenses) * Decimal("100") / Decimal("122")
    osno_profit_tax = (profit_net * Decimal("25") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) if profit_net > 0 else Decimal("0")
    osno_total = vat_due + osno_profit_tax

    # Патент
    patent_tax = Decimal("0")
    if potential_income_patent > 0:
        patent_tax = (potential_income_patent * Decimal("6") / Decimal("100")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        patent_tax = max(Decimal("0"), patent_tax - ip_insurance)

    results = {
        "УСН 6%": usn6_tax + ip_insurance,
        "УСН 15%": usn15_tax + ip_insurance,
        "ОСНО": osno_total + ip_insurance,
    }
    if potential_income_patent > 0:
        results["Патент"] = patent_tax + ip_insurance

    best = min(results, key=results.get)

    return {
        "input": {"revenue": revenue, "expenses": expenses},
        "results": {k: float(v) for k, v in results.items()},
        "best_regime": best,
        "best_amount": float(results[best]),
    }

result = compare_tax_regimes(Decimal("5000000"), Decimal("3000000"), Decimal("1500000"))

Ставки актуальны на 2026 год. МРОТ: 27 093 руб. Фиксированные взносы ИП: 55 766 руб.

Skill-файл содержит паттерны кода для финансовых расчётов. Выполняй код через sandbox_bash.

Категория
📊 Документы и расчёты
Платформа
Сам Решу

Попробуйте этот навык

Зарегистрируйтесь и используйте навык «Калькулятор с русской локалью» бесплатно.