frontend költség beállítások

This commit is contained in:
Roo
2026-06-23 21:11:21 +00:00
parent 5b437b220d
commit 71ef33bb85
90 changed files with 11850 additions and 1053 deletions

View File

@@ -0,0 +1,242 @@
# /opt/docker/dev/service_finder/backend/app/schemas/fleet_finance.py
"""
Pydantic sémák a flotta pénzügyi modelljeihez.
- AssetFinancials: Beszerzés, finanszírozás, értékcsökkenés
- InsuranceProvider: Biztosítók katalógusa
- VehicleInsurancePolicy: Jármű biztosítási kötvények
- VehicleTaxObligation: Jármű adókötelezettségek
"""
from pydantic import BaseModel, ConfigDict, Field, field_validator
from typing import Optional, Dict, Any, List
from uuid import UUID
from datetime import datetime, date
# =============================================================================
# AssetFinancials sémák
# =============================================================================
class AssetFinancialsUpdate(BaseModel):
"""AssetFinancials frissítése - minden mező opcionális."""
purchase_price_net: Optional[float] = Field(None, ge=0, description="Nettó vételár")
purchase_price_gross: Optional[float] = Field(None, ge=0, description="Bruttó vételár")
vat_rate: Optional[float] = Field(None, ge=0, le=100, description="ÁFA kulcs (%)")
activation_date: Optional[datetime] = Field(None, description="Aktiválás dátuma")
verified_purchase_date: Optional[datetime] = Field(None, description="Ellenőrzött vásárlási dátum")
financing_type: Optional[str] = Field(None, max_length=50, description="Finanszírozás típusa (cash, loan, lease)")
accounting_details: Optional[Dict[str, Any]] = Field(None, description="Számviteli részletek (JSONB)")
# Finanszírozás
down_payment: Optional[float] = Field(None, ge=0, description="Önerő")
monthly_installment: Optional[float] = Field(None, ge=0, description="Havi törlesztő")
residual_value: Optional[float] = Field(None, ge=0, description="Maradványérték")
contract_number: Optional[str] = Field(None, max_length=100, description="Szerződésszám")
financing_provider: Optional[str] = Field(None, max_length=200, description="Finanszírozó")
interest_rate: Optional[float] = Field(None, ge=0, le=100, description="Kamatláb (%)")
total_contract_value: Optional[float] = Field(None, ge=0, description="Teljes szerződéses érték")
lease_start_date: Optional[date] = Field(None, description="Lízing kezdete")
lease_end_date: Optional[date] = Field(None, description="Lízing vége")
model_config = ConfigDict(from_attributes=True)
class AssetFinancialsResponse(BaseModel):
"""AssetFinancials teljes válaszmodell."""
id: int
asset_id: UUID
# Beszerzés
purchase_price_net: float
purchase_price_gross: float
vat_rate: float
activation_date: Optional[datetime] = None
verified_purchase_date: Optional[datetime] = None
financing_type: str
accounting_details: Dict[str, Any] = Field(default_factory=dict)
# Finanszírozás
down_payment: Optional[float] = None
monthly_installment: Optional[float] = None
residual_value: Optional[float] = None
contract_number: Optional[str] = None
financing_provider: Optional[str] = None
interest_rate: Optional[float] = None
total_contract_value: Optional[float] = None
lease_start_date: Optional[date] = None
lease_end_date: Optional[date] = None
model_config = ConfigDict(from_attributes=True)
# =============================================================================
# InsuranceProvider sémák
# =============================================================================
class InsuranceProviderResponse(BaseModel):
"""Biztosító teljes válaszmodell."""
id: int
name: str
country_code: Optional[str] = Field(None, max_length=2, description="ISO 3166-1 alpha-2 országkód (pl. 'HU'). Ha None, akkor globális.")
claim_phone: Optional[str] = None
claim_url: Optional[str] = None
services_offered: Dict[str, Any] = Field(default_factory=dict)
is_active: bool = True
model_config = ConfigDict(from_attributes=True)
class InsuranceProviderCreate(BaseModel):
"""Új biztosító létrehozása."""
name: str = Field(..., min_length=1, max_length=150, description="Biztosító neve")
country_code: Optional[str] = Field(None, max_length=2, description="ISO 3166-1 alpha-2 országkód (pl. 'HU'). Ha None, akkor globális.")
claim_phone: Optional[str] = Field(None, max_length=50, description="Kárbejelentő telefonszám")
claim_url: Optional[str] = Field(None, max_length=255, description="Kárbejelentő URL")
services_offered: Optional[Dict[str, Any]] = Field(None, description="Kínált szolgáltatások (JSONB)")
is_active: bool = Field(default=True, description="Aktív-e")
model_config = ConfigDict(from_attributes=True)
class InsuranceProviderUpdate(BaseModel):
"""Biztosító frissítése - minden mező opcionális."""
name: Optional[str] = Field(None, min_length=1, max_length=150, description="Biztosító neve")
country_code: Optional[str] = Field(None, max_length=2, description="ISO 3166-1 alpha-2 országkód (pl. 'HU'). Ha None, akkor globális.")
claim_phone: Optional[str] = Field(None, max_length=50, description="Kárbejelentő telefonszám")
claim_url: Optional[str] = Field(None, max_length=255, description="Kárbejelentő URL")
services_offered: Optional[Dict[str, Any]] = Field(None, description="Kínált szolgáltatások (JSONB)")
is_active: Optional[bool] = Field(None, description="Aktív-e")
model_config = ConfigDict(from_attributes=True)
# =============================================================================
# VehicleInsurancePolicy sémák
# =============================================================================
class VehicleInsurancePolicyCreate(BaseModel):
"""Új biztosítási kötvény létrehozása."""
provider_id: int = Field(..., description="Biztosító ID (insurance_providers tábla)")
insurance_type: str = Field(..., max_length=20, description="Biztosítás típusa (KGFB, CASCO)")
policy_number: str = Field(..., max_length=100, description="Kötvényszám")
start_date: date = Field(..., description="Biztosítás kezdete")
expiry_date: date = Field(..., description="Biztosítás lejárata")
premium_amount: float = Field(..., ge=0, description="Díj összege")
currency: str = Field(default="HUF", max_length=3, description="Pénznem")
document_id: Optional[UUID] = Field(None, description="Kapcsolódó dokumentum ID (PDF kötvény)")
@field_validator('insurance_type')
@classmethod
def validate_insurance_type(cls, v: str) -> str:
"""insurance_type csak KGFB vagy CASCO lehet."""
allowed = {"KGFB", "CASCO"}
cleaned = v.strip().upper()
if cleaned not in allowed:
raise ValueError(f'A biztosítás típusa csak {allowed} lehet, kapott: "{v}"')
return cleaned
@field_validator('expiry_date')
@classmethod
def validate_expiry_after_start(cls, v: date, info):
"""expiry_date nem lehet a start_date előtt."""
values = info.data
start = values.get('start_date')
if start and v <= start:
raise ValueError('A biztosítás lejárati dátuma nem lehet a kezdő dátum előtt vagy azzal egyenlő')
return v
model_config = ConfigDict(from_attributes=True)
class VehicleInsurancePolicyUpdate(BaseModel):
"""Biztosítási kötvény frissítése - minden mező opcionális."""
provider_id: Optional[int] = Field(None, description="Biztosító ID")
insurance_type: Optional[str] = Field(None, max_length=20, description="Biztosítás típusa")
policy_number: Optional[str] = Field(None, max_length=100, description="Kötvényszám")
start_date: Optional[date] = Field(None, description="Biztosítás kezdete")
expiry_date: Optional[date] = Field(None, description="Biztosítás lejárata")
premium_amount: Optional[float] = Field(None, ge=0, description="Díj összege")
currency: Optional[str] = Field(None, max_length=3, description="Pénznem")
document_id: Optional[UUID] = Field(None, description="Kapcsolódó dokumentum ID (PDF kötvény)")
model_config = ConfigDict(from_attributes=True)
class VehicleInsurancePolicyResponse(BaseModel):
"""Biztosítási kötvény teljes válaszmodell."""
id: UUID
asset_id: UUID
provider_id: int
insurance_type: str
policy_number: str
start_date: date
expiry_date: date
premium_amount: float
currency: str
document_id: Optional[UUID] = None
model_config = ConfigDict(from_attributes=True)
# =============================================================================
# VehicleTaxObligation sémák
# =============================================================================
class VehicleTaxObligationCreate(BaseModel):
"""Új adókötelezettség létrehozása."""
tax_type: str = Field(..., max_length=30, description="Adó típusa (WEIGHT_TAX, COMPANY_CAR_TAX)")
tax_year: int = Field(..., ge=2000, le=2100, description="Adóév")
amount: float = Field(..., ge=0, description="Adó összege")
currency: str = Field(default="HUF", max_length=3, description="Pénznem")
due_date: Optional[date] = Field(None, description="Fizetési határidő")
payment_status: str = Field(default="pending", max_length=20, description="Fizetési státusz")
document_id: Optional[UUID] = Field(None, description="Kapcsolódó dokumentum ID (PDF adóbevallás)")
@field_validator('tax_type')
@classmethod
def validate_tax_type(cls, v: str) -> str:
"""tax_type csak WEIGHT_TAX vagy COMPANY_CAR_TAX lehet."""
allowed = {"WEIGHT_TAX", "COMPANY_CAR_TAX"}
cleaned = v.strip().upper()
if cleaned not in allowed:
raise ValueError(f'Az adó típusa csak {allowed} lehet, kapott: "{v}"')
return cleaned
@field_validator('payment_status')
@classmethod
def validate_payment_status(cls, v: str) -> str:
"""payment_status csak pending, paid, overdue lehet."""
allowed = {"pending", "paid", "overdue"}
cleaned = v.strip().lower()
if cleaned not in allowed:
raise ValueError(f'A fizetési státusz csak {allowed} lehet, kapott: "{v}"')
return cleaned
model_config = ConfigDict(from_attributes=True)
class VehicleTaxObligationUpdate(BaseModel):
"""Adókötelezettség frissítése - minden mező opcionális."""
tax_type: Optional[str] = Field(None, max_length=30, description="Adó típusa")
tax_year: Optional[int] = Field(None, ge=2000, le=2100, description="Adóév")
amount: Optional[float] = Field(None, ge=0, description="Adó összege")
currency: Optional[str] = Field(None, max_length=3, description="Pénznem")
due_date: Optional[date] = Field(None, description="Fizetési határidő")
payment_status: Optional[str] = Field(None, max_length=20, description="Fizetési státusz")
document_id: Optional[UUID] = Field(None, description="Kapcsolódó dokumentum ID (PDF adóbevallás)")
model_config = ConfigDict(from_attributes=True)
class VehicleTaxObligationResponse(BaseModel):
"""Adókötelezettség teljes válaszmodell."""
id: UUID
asset_id: UUID
tax_type: str
tax_year: int
amount: float
currency: str
due_date: Optional[date] = None
payment_status: str
document_id: Optional[UUID] = None
model_config = ConfigDict(from_attributes=True)