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

@@ -12,11 +12,17 @@ from sqlalchemy.orm import selectinload
from app.db.session import get_db
from app.api.deps import get_current_user
from app.models import Asset, AssetCatalog, AssetCost, AssetEvent, OdometerReading, CostCategory, OrganizationMember, OrgRole
from app.models.fleet_finance import AssetFinancials, VehicleInsurancePolicy, VehicleTaxObligation
from app.models.identity import User
from app.services.cost_service import cost_service
from app.services.asset_service import AssetService
from app.schemas.asset_cost import AssetCostCreate, AssetCostResponse
from app.schemas.asset import AssetResponse, AssetCreate, AssetUpdate, AssetEventCreate, AssetEventResponse
from app.schemas.fleet_finance import (
AssetFinancialsUpdate, AssetFinancialsResponse,
VehicleInsurancePolicyCreate, VehicleInsurancePolicyUpdate, VehicleInsurancePolicyResponse,
VehicleTaxObligationCreate, VehicleTaxObligationUpdate, VehicleTaxObligationResponse,
)
logger = logging.getLogger(__name__)
@@ -1228,4 +1234,363 @@ async def archive_vehicle(
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Belső szerverhiba a jármű archiválásakor"
)
)
# =============================================================================
# Fleet Finance endpoints
# =============================================================================
@router.get(
"/vehicles/{asset_id}/financials",
response_model=AssetFinancialsResponse,
)
async def get_vehicle_financials(
asset_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Jármű pénzügyi adatainak lekérése.
GET /api/v1/assets/vehicles/{asset_id}/financials
Visszaadja a jármű beszerzési, finanszírozási és lízing adatait.
"""
asset = await _check_asset_access(db, asset_id, current_user)
stmt = select(AssetFinancials).where(AssetFinancials.asset_id == asset_id)
result = await db.execute(stmt)
financials = result.scalar_one_or_none()
if not financials:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="A járműhöz nem található pénzügyi adat"
)
return financials
@router.patch(
"/vehicles/{asset_id}/financials",
response_model=AssetFinancialsResponse,
)
async def update_vehicle_financials(
asset_id: uuid.UUID,
payload: AssetFinancialsUpdate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Jármű pénzügyi adatainak frissítése.
PATCH /api/v1/assets/vehicles/{asset_id}/financials
Csak a megadott mezőket frissíti (partial update).
"""
asset = await _check_asset_access(db, asset_id, current_user)
stmt = select(AssetFinancials).where(AssetFinancials.asset_id == asset_id)
result = await db.execute(stmt)
financials = result.scalar_one_or_none()
if not financials:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="A járműhöz nem található pénzügyi adat"
)
# Partial update: csak a megadott mezőket frissítjük
update_data = payload.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(financials, field, value)
await db.commit()
await db.refresh(financials)
return financials
@router.get(
"/vehicles/{asset_id}/insurance",
response_model=List[VehicleInsurancePolicyResponse],
)
async def list_vehicle_insurance_policies(
asset_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Jármű biztosítási kötvényeinek listázása.
GET /api/v1/assets/vehicles/{asset_id}/insurance
Visszaadja a járműhöz tartozó összes biztosítási kötvényt.
"""
asset = await _check_asset_access(db, asset_id, current_user)
stmt = (
select(VehicleInsurancePolicy)
.where(VehicleInsurancePolicy.asset_id == asset_id)
.order_by(VehicleInsurancePolicy.start_date.desc())
)
result = await db.execute(stmt)
policies = result.scalars().all()
return policies
@router.post(
"/vehicles/{asset_id}/insurance",
response_model=VehicleInsurancePolicyResponse,
status_code=status.HTTP_201_CREATED,
)
async def create_vehicle_insurance_policy(
asset_id: uuid.UUID,
payload: VehicleInsurancePolicyCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Új biztosítási kötvény létrehozása a járműhöz.
POST /api/v1/assets/vehicles/{asset_id}/insurance
"""
asset = await _check_asset_access(db, asset_id, current_user)
policy = VehicleInsurancePolicy(
asset_id=asset_id,
provider_id=payload.provider_id,
insurance_type=payload.insurance_type,
policy_number=payload.policy_number,
start_date=payload.start_date,
expiry_date=payload.expiry_date,
premium_amount=payload.premium_amount,
currency=payload.currency,
)
db.add(policy)
await db.commit()
await db.refresh(policy)
return policy
@router.get(
"/vehicles/{asset_id}/tax",
response_model=List[VehicleTaxObligationResponse],
)
async def list_vehicle_tax_obligations(
asset_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Jármű adókötelezettségeinek listázása.
GET /api/v1/assets/vehicles/{asset_id}/tax
Visszaadja a járműhöz tartozó összes adókötelezettséget.
"""
asset = await _check_asset_access(db, asset_id, current_user)
stmt = (
select(VehicleTaxObligation)
.where(VehicleTaxObligation.asset_id == asset_id)
.order_by(VehicleTaxObligation.tax_year.desc())
)
result = await db.execute(stmt)
obligations = result.scalars().all()
return obligations
@router.post(
"/vehicles/{asset_id}/tax",
response_model=VehicleTaxObligationResponse,
status_code=status.HTTP_201_CREATED,
)
async def create_vehicle_tax_obligation(
asset_id: uuid.UUID,
payload: VehicleTaxObligationCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Új adókötelezettség létrehozása a járműhöz.
POST /api/v1/assets/vehicles/{asset_id}/tax
"""
asset = await _check_asset_access(db, asset_id, current_user)
obligation = VehicleTaxObligation(
asset_id=asset_id,
tax_type=payload.tax_type,
tax_year=payload.tax_year,
amount=payload.amount,
currency=payload.currency,
due_date=payload.due_date,
payment_status=payload.payment_status,
)
db.add(obligation)
await db.commit()
await db.refresh(obligation)
return obligation
# =============================================================================
# VehicleInsurancePolicy PUT / DELETE
# =============================================================================
@router.put(
"/vehicles/{asset_id}/insurance/{policy_id}",
response_model=VehicleInsurancePolicyResponse,
)
async def update_vehicle_insurance_policy(
asset_id: uuid.UUID,
policy_id: uuid.UUID,
payload: VehicleInsurancePolicyUpdate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Biztosítási kötvény módosítása.
PUT /api/v1/assets/vehicles/{asset_id}/insurance/{policy_id}
Csak a megadott mezőket frissíti (partial update).
"""
await _check_asset_access(db, asset_id, current_user)
stmt = select(VehicleInsurancePolicy).where(
VehicleInsurancePolicy.id == policy_id,
VehicleInsurancePolicy.asset_id == asset_id,
)
result = await db.execute(stmt)
policy = result.scalar_one_or_none()
if not policy:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Biztosítási kötvény nem található",
)
update_data = payload.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(policy, field, value)
await db.commit()
await db.refresh(policy)
return policy
@router.delete(
"/vehicles/{asset_id}/insurance/{policy_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_vehicle_insurance_policy(
asset_id: uuid.UUID,
policy_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Biztosítási kötvény törlése.
DELETE /api/v1/assets/vehicles/{asset_id}/insurance/{policy_id}
"""
await _check_asset_access(db, asset_id, current_user)
stmt = select(VehicleInsurancePolicy).where(
VehicleInsurancePolicy.id == policy_id,
VehicleInsurancePolicy.asset_id == asset_id,
)
result = await db.execute(stmt)
policy = result.scalar_one_or_none()
if not policy:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Biztosítási kötvény nem található",
)
await db.delete(policy)
await db.commit()
# =============================================================================
# VehicleTaxObligation PUT / DELETE
# =============================================================================
@router.put(
"/vehicles/{asset_id}/tax/{tax_id}",
response_model=VehicleTaxObligationResponse,
)
async def update_vehicle_tax_obligation(
asset_id: uuid.UUID,
tax_id: uuid.UUID,
payload: VehicleTaxObligationUpdate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Adókötelezettség módosítása.
PUT /api/v1/assets/vehicles/{asset_id}/tax/{tax_id}
Csak a megadott mezőket frissíti (partial update).
"""
await _check_asset_access(db, asset_id, current_user)
stmt = select(VehicleTaxObligation).where(
VehicleTaxObligation.id == tax_id,
VehicleTaxObligation.asset_id == asset_id,
)
result = await db.execute(stmt)
obligation = result.scalar_one_or_none()
if not obligation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Adókötelezettség nem található",
)
update_data = payload.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(obligation, field, value)
await db.commit()
await db.refresh(obligation)
return obligation
@router.delete(
"/vehicles/{asset_id}/tax/{tax_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_vehicle_tax_obligation(
asset_id: uuid.UUID,
tax_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
Adókötelezettség törlése.
DELETE /api/v1/assets/vehicles/{asset_id}/tax/{tax_id}
"""
await _check_asset_access(db, asset_id, current_user)
stmt = select(VehicleTaxObligation).where(
VehicleTaxObligation.id == tax_id,
VehicleTaxObligation.asset_id == asset_id,
)
result = await db.execute(stmt)
obligation = result.scalar_one_or_none()
if not obligation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Adókötelezettség nem található",
)
await db.delete(obligation)
await db.commit()