финальная версия Finance Control
This commit is contained in:
0
app/utils/__init__.py
Normal file
0
app/utils/__init__.py
Normal file
25
app/utils/formatters.py
Normal file
25
app/utils/formatters.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from datetime import date, datetime
|
||||
|
||||
|
||||
def format_money(value: float | int | None) -> str:
|
||||
"""Return money value in a readable Russian format."""
|
||||
amount = 0 if value is None else float(value)
|
||||
return f"{amount:,.2f} ₽".replace(",", " ")
|
||||
|
||||
|
||||
def current_month_key() -> str:
|
||||
"""Return current month in SQLite-friendly format YYYY-MM."""
|
||||
return date.today().strftime("%Y-%m")
|
||||
|
||||
|
||||
def today_text() -> str:
|
||||
"""Return current date in ISO format for entry fields."""
|
||||
return date.today().strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
def validate_date(value: str) -> str:
|
||||
"""Validate user date and return normalized ISO date."""
|
||||
try:
|
||||
return datetime.strptime(value.strip(), "%Y-%m-%d").strftime("%Y-%m-%d")
|
||||
except ValueError as error:
|
||||
raise ValueError("Дата должна быть в формате ГГГГ-ММ-ДД.") from error
|
||||
40
app/utils/validators.py
Normal file
40
app/utils/validators.py
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
def normalize_text(value: str, field_name: str, max_length: int = 80) -> str:
|
||||
"""Strip and validate a required text value."""
|
||||
text = value.strip()
|
||||
if not text:
|
||||
raise ValueError(f"Поле «{field_name}» не должно быть пустым.")
|
||||
if len(text) > max_length:
|
||||
raise ValueError(
|
||||
f"Поле «{field_name}» должно быть не длиннее {max_length} символов."
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
def parse_float(value: str, field_name: str) -> float:
|
||||
"""Parse a float from Russian-style user input."""
|
||||
prepared = value.strip().replace(" ", "").replace(",", ".")
|
||||
try:
|
||||
number = float(prepared)
|
||||
except ValueError as error:
|
||||
raise ValueError(f"Поле «{field_name}» должно быть числом.") from error
|
||||
return number
|
||||
|
||||
|
||||
def parse_positive_float(value: str, field_name: str) -> float:
|
||||
"""Parse a strictly positive float."""
|
||||
number = parse_float(value, field_name)
|
||||
if number <= 0:
|
||||
raise ValueError(f"Поле «{field_name}» должно быть больше нуля.")
|
||||
return number
|
||||
|
||||
|
||||
def parse_billing_day(value: str) -> int:
|
||||
"""Parse subscription billing day."""
|
||||
try:
|
||||
day = int(value.strip())
|
||||
except ValueError as error:
|
||||
raise ValueError("День списания должен быть целым числом от 1 до 31.") from error
|
||||
if not 1 <= day <= 31:
|
||||
raise ValueError("День списания должен быть в диапазоне от 1 до 31.")
|
||||
return day
|
||||
Reference in New Issue
Block a user