átlagos kiegészítséek jó sok

This commit is contained in:
Roo
2026-03-22 11:02:05 +00:00
parent f53e0b53df
commit 5d44339f21
249 changed files with 20922 additions and 2253 deletions

View File

@@ -0,0 +1,258 @@
# /opt/docker/dev/service_finder/backend/app/models/vehicle/asset.py
from __future__ import annotations
import uuid
from datetime import datetime
from typing import List, Optional, TYPE_CHECKING
from sqlalchemy import String, Boolean, DateTime, ForeignKey, Numeric, text, Text, UniqueConstraint, BigInteger, Integer, Float
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID as PG_UUID, JSONB
from sqlalchemy.sql import func
from app.database import Base
class AssetCatalog(Base):
""" Jármű katalógus mesteradatok (Validált technikai sablonok). """
__tablename__ = "vehicle_catalog"
__table_args__ = (
UniqueConstraint('make', 'model', 'year_from', 'fuel_type', name='uix_vehicle_catalog_full'),
{"schema": "vehicle"}
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
master_definition_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("vehicle.vehicle_model_definitions.id"))
make: Mapped[str] = mapped_column(String, index=True, nullable=False)
model: Mapped[str] = mapped_column(String, index=True, nullable=False)
generation: Mapped[Optional[str]] = mapped_column(String, index=True)
year_from: Mapped[Optional[int]] = mapped_column(Integer)
year_to: Mapped[Optional[int]] = mapped_column(Integer)
fuel_type: Mapped[Optional[str]] = mapped_column(String, index=True)
power_kw: Mapped[Optional[int]] = mapped_column(Integer, index=True)
engine_capacity: Mapped[Optional[int]] = mapped_column(Integer, index=True)
factory_data: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
master_definition: Mapped[Optional["VehicleModelDefinition"]] = relationship("VehicleModelDefinition", back_populates="variants")
assets: Mapped[List["Asset"]] = relationship("Asset", back_populates="catalog")
class Asset(Base):
""" A fizikai eszköz (Digital Twin) - Minden adat itt fut össze. """
__tablename__ = "assets"
__table_args__ = {"schema": "vehicle"}
id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
vin: Mapped[str] = mapped_column(String(17), unique=True, index=True, nullable=False)
license_plate: Mapped[Optional[str]] = mapped_column(String(20), index=True)
name: Mapped[Optional[str]] = mapped_column(String)
# Állapot és életút mérőszámok
year_of_manufacture: Mapped[Optional[int]] = mapped_column(Integer, index=True)
first_registration_date: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
current_mileage: Mapped[int] = mapped_column(Integer, default=0, index=True)
condition_score: Mapped[int] = mapped_column(Integer, default=100)
# Értékesítési modul
is_for_sale: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
price: Mapped[Optional[float]] = mapped_column(Numeric(15, 2))
currency: Mapped[str] = mapped_column(String(3), default="EUR")
catalog_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("vehicle.vehicle_catalog.id"))
current_organization_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("fleet.organizations.id"))
# Identity kapcsolatok
owner_person_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("identity.persons.id"))
owner_org_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("fleet.organizations.id"))
operator_person_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("identity.persons.id"))
operator_org_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("fleet.organizations.id"))
status: Mapped[str] = mapped_column(String(20), default="active")
individual_equipment: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), onupdate=func.now())
# --- KAPCSOLATOK ---
catalog: Mapped["AssetCatalog"] = relationship("AssetCatalog", back_populates="assets")
financials: Mapped[Optional["AssetFinancials"]] = relationship("AssetFinancials", back_populates="asset", uselist=False)
costs: Mapped[List["AssetCost"]] = relationship("AssetCost", back_populates="asset")
events: Mapped[List["AssetEvent"]] = relationship("AssetEvent", back_populates="asset")
logbook: Mapped[List["VehicleLogbook"]] = relationship("VehicleLogbook", back_populates="asset")
inspections: Mapped[List["AssetInspection"]] = relationship("AssetInspection", back_populates="asset")
reviews: Mapped[List["AssetReview"]] = relationship("AssetReview", back_populates="asset")
telemetry: Mapped[Optional["AssetTelemetry"]] = relationship("AssetTelemetry", back_populates="asset", uselist=False)
assignments: Mapped[List["AssetAssignment"]] = relationship("AssetAssignment", back_populates="asset")
ownership_history: Mapped[List["VehicleOwnership"]] = relationship("VehicleOwnership", back_populates="asset")
# --- COMPUTED PROPERTIES (for Pydantic schema compatibility) ---
@property
def is_verified(self) -> bool:
"""Always False for now, as verification is not yet implemented."""
return False
class AssetFinancials(Base):
""" I. Beszerzés és IV. Értékcsökkenés (Amortizáció). """
__tablename__ = "asset_financials"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), unique=True)
purchase_price_net: Mapped[float] = mapped_column(Numeric(18, 2))
purchase_price_gross: Mapped[float] = mapped_column(Numeric(18, 2))
vat_rate: Mapped[float] = mapped_column(Numeric(5, 2), default=27.00)
activation_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
financing_type: Mapped[str] = mapped_column(String(50))
accounting_details: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
asset: Mapped["Asset"] = relationship("Asset", back_populates="financials")
class AssetCost(Base):
""" II. Üzemeltetés és TCO kimutatás. """
__tablename__ = "asset_costs"
__table_args__ = {"schema": "vehicle"}
id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
organization_id: Mapped[int] = mapped_column(Integer, ForeignKey("fleet.organizations.id"), nullable=False)
cost_category: Mapped[str] = mapped_column(String(50), index=True)
amount_net: Mapped[float] = mapped_column(Numeric(18, 2), nullable=False)
currency: Mapped[str] = mapped_column(String(3), default="HUF")
date: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
invoice_number: Mapped[Optional[str]] = mapped_column(String(100), index=True)
data: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
asset: Mapped["Asset"] = relationship("Asset", back_populates="costs")
organization: Mapped["Organization"] = relationship("Organization")
class VehicleLogbook(Base):
""" Útnyilvántartás (NAV, Kiküldetés, Munkábajárás). """
__tablename__ = "vehicle_logbook"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
driver_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False)
trip_type: Mapped[str] = mapped_column(String(30), index=True)
is_reimbursable: Mapped[bool] = mapped_column(Boolean, default=False)
start_mileage: Mapped[int] = mapped_column(Integer)
end_mileage: Mapped[Optional[int]] = mapped_column(Integer)
distance_km: Mapped[Optional[float]] = mapped_column(Numeric(10, 2), nullable=True)
# GPS koordináták
start_lat: Mapped[Optional[float]] = mapped_column(Numeric(10, 6), nullable=True)
start_lng: Mapped[Optional[float]] = mapped_column(Numeric(10, 6), nullable=True)
end_lat: Mapped[Optional[float]] = mapped_column(Numeric(10, 6), nullable=True)
end_lng: Mapped[Optional[float]] = mapped_column(Numeric(10, 6), nullable=True)
gps_calculated_distance: Mapped[Optional[float]] = mapped_column(Numeric(10, 2), nullable=True)
# OBDII és telemetria
obd_verified: Mapped[bool] = mapped_column(Boolean, default=False)
max_acceleration: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
average_speed: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
asset: Mapped["Asset"] = relationship("Asset", back_populates="logbook")
driver: Mapped["User"] = relationship("User")
class AssetInspection(Base):
""" Napi ellenőrző lista és Biztonsági check. """
__tablename__ = "asset_inspections"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
inspector_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False)
timestamp: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
checklist_results: Mapped[dict] = mapped_column(JSONB, nullable=False)
is_safe: Mapped[bool] = mapped_column(Boolean, default=True)
asset: Mapped["Asset"] = relationship("Asset", back_populates="inspections")
inspector: Mapped["User"] = relationship("User")
class AssetReview(Base):
""" Jármű értékelések és visszajelzések. """
__tablename__ = "asset_reviews"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False)
overall_rating: Mapped[Optional[int]] = mapped_column(Integer) # 1-5 csillag
comment: Mapped[Optional[str]] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
asset: Mapped["Asset"] = relationship("Asset", back_populates="reviews")
user: Mapped["User"] = relationship("User")
class VehicleOwnership(Base):
""" Tulajdonosváltások története. """
__tablename__ = "vehicle_ownership_history"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False)
acquired_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
disposed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
asset: Mapped["Asset"] = relationship("Asset", back_populates="ownership_history")
# JAVÍTVA: Kapcsolat a User modellhez
user: Mapped["User"] = relationship("User", back_populates="ownership_history")
class AssetTelemetry(Base):
__tablename__ = "asset_telemetry"
__table_args__ = {"schema": "vehicle"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), unique=True)
current_mileage: Mapped[int] = mapped_column(Integer, default=0)
asset: Mapped["Asset"] = relationship("Asset", back_populates="telemetry")
class AssetAssignment(Base):
""" Eszköz-Szervezet összerendelés. """
__tablename__ = "asset_assignments"
__table_args__ = {"schema": "fleet"}
id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
organization_id: Mapped[int] = mapped_column(Integer, ForeignKey("fleet.organizations.id"), nullable=False)
status: Mapped[str] = mapped_column(String(30), default="active")
asset: Mapped["Asset"] = relationship("Asset", back_populates="assignments")
organization: Mapped["Organization"] = relationship("Organization", back_populates="assets")
class AssetEvent(Base):
""" Szerviz, baleset és egyéb jelentős események. """
__tablename__ = "asset_events"
__table_args__ = {"schema": "vehicle"}
id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
asset_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.assets.id"), nullable=False)
event_type: Mapped[str] = mapped_column(String(50), nullable=False)
asset: Mapped["Asset"] = relationship("Asset", back_populates="events")
class ExchangeRate(Base):
__tablename__ = "exchange_rates"
__table_args__ = {"schema": "finance"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
rate: Mapped[float] = mapped_column(Numeric(18, 6), nullable=False)
class CatalogDiscovery(Base):
""" Robot munkaterület a felfedezett modelleknek. """
__tablename__ = "catalog_discovery"
__table_args__ = (
# KIBŐVÍTETT EGYEDISÉGI SZABÁLY: Márka + Modell + Osztály + Piac + Évjárat
UniqueConstraint('make', 'model', 'vehicle_class', 'market', 'model_year', name='_make_model_market_year_uc'),
# Alapvető egyediség: make + model + vehicle_class (piac és évjárat nélkül)
UniqueConstraint('make', 'model', 'vehicle_class', name='uq_make_model_class'),
{"schema": "vehicle"}
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
make: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
model: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
vehicle_class: Mapped[str] = mapped_column(String(50), server_default=text("'car'"), index=True)
# --- ÚJ MEZŐK A STATISZTIKÁHOZ ÉS PIACAZONOSÍTÁSHOZ ---
market: Mapped[str] = mapped_column(String(20), server_default=text("'GLOBAL'"), index=True) # pl: RDW, DVLA, USA_IMPORT
model_year: Mapped[Optional[int]] = mapped_column(Integer, index=True)
# Robot vezérlés
status: Mapped[str] = mapped_column(String(20), server_default=text("'pending'"), index=True)
source: Mapped[Optional[str]] = mapped_column(String(100)) # pl: STRATEGIST-V2, NHTSA-V1
priority_score: Mapped[int] = mapped_column(Integer, server_default=text("0"))
attempts: Mapped[int] = mapped_column(Integer, server_default=text("0"))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())