186 lines
8.3 KiB
Python
186 lines
8.3 KiB
Python
import uuid
|
|
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Numeric, text, Text, UniqueConstraint
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.dialects.postgresql import UUID as PG_UUID, JSONB
|
|
from sqlalchemy.sql import func
|
|
from app.db.base_class import Base
|
|
|
|
class AssetCatalog(Base):
|
|
__tablename__ = "vehicle_catalog"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
'make', 'model', 'year_from', 'engine_variant', 'fuel_type',
|
|
name='uix_vehicle_catalog_full'
|
|
),
|
|
{"schema": "data"}
|
|
)
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
make = Column(String, index=True, nullable=False)
|
|
model = Column(String, index=True, nullable=False)
|
|
generation = Column(String, index=True)
|
|
engine_variant = Column(String, index=True)
|
|
year_from = Column(Integer)
|
|
year_to = Column(Integer)
|
|
vehicle_class = Column(String)
|
|
fuel_type = Column(String, index=True)
|
|
|
|
# --- ÚJ OSZLOPOK (Ezeket add hozzá!) ---
|
|
power_kw = Column(Integer, index=True)
|
|
engine_capacity = Column(Integer, index=True)
|
|
max_weight_kg = Column(Integer)
|
|
axle_count = Column(Integer)
|
|
euro_class = Column(String(20))
|
|
body_type = Column(String(100))
|
|
# ---------------------------------------
|
|
|
|
engine_code = Column(String)
|
|
factory_data = Column(JSONB, server_default=text("'{}'::jsonb"))
|
|
|
|
assets = relationship("Asset", back_populates="catalog")
|
|
|
|
class Asset(Base):
|
|
__tablename__ = "assets"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
vin = Column(String(17), unique=True, index=True, nullable=False)
|
|
license_plate = Column(String(20), index=True)
|
|
name = Column(String)
|
|
year_of_manufacture = Column(Integer)
|
|
current_organization_id = Column(Integer, ForeignKey("data.organizations.id"), nullable=True)
|
|
catalog_id = Column(Integer, ForeignKey("data.vehicle_catalog.id"))
|
|
|
|
# Moderációs mezők a Robot 3 (OCR) számára
|
|
is_verified = Column(Boolean, default=False)
|
|
verification_method = Column(String(20)) # 'manual', 'ocr', 'vin_api'
|
|
verification_notes = Column(Text, nullable=True) # Eltérések jegyzőkönyve
|
|
catalog_match_score = Column(Numeric(5, 2), nullable=True) # 0-100% egyezési arány
|
|
|
|
status = Column(String(20), default="active")
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
catalog = relationship("AssetCatalog", back_populates="assets")
|
|
current_org = relationship("Organization")
|
|
financials = relationship("AssetFinancials", back_populates="asset", uselist=False)
|
|
telemetry = relationship("AssetTelemetry", back_populates="asset", uselist=False)
|
|
assignments = relationship("AssetAssignment", back_populates="asset")
|
|
events = relationship("AssetEvent", back_populates="asset")
|
|
costs = relationship("AssetCost", back_populates="asset")
|
|
reviews = relationship("AssetReview", back_populates="asset")
|
|
ownership_history = relationship("VehicleOwnership", back_populates="vehicle")
|
|
|
|
class AssetFinancials(Base):
|
|
__tablename__ = "asset_financials"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(Integer, primary_key=True)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), unique=True)
|
|
acquisition_price = Column(Numeric(18, 2))
|
|
acquisition_date = Column(DateTime)
|
|
financing_type = Column(String)
|
|
residual_value_estimate = Column(Numeric(18, 2))
|
|
asset = relationship("Asset", back_populates="financials")
|
|
|
|
class AssetTelemetry(Base):
|
|
__tablename__ = "asset_telemetry"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(Integer, primary_key=True)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), unique=True)
|
|
current_mileage = Column(Integer, default=0)
|
|
mileage_unit = Column(String(10), default="km")
|
|
vqi_score = Column(Numeric(5, 2), default=100.00)
|
|
dbs_score = Column(Numeric(5, 2), default=100.00)
|
|
asset = relationship("Asset", back_populates="telemetry")
|
|
|
|
class AssetReview(Base):
|
|
__tablename__ = "asset_reviews"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(Integer, primary_key=True)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), nullable=False)
|
|
user_id = Column(Integer, ForeignKey("data.users.id"), nullable=False)
|
|
overall_rating = Column(Integer)
|
|
criteria_scores = Column(JSONB, server_default=text("'{}'::jsonb"))
|
|
comment = Column(Text)
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
asset = relationship("Asset", back_populates="reviews")
|
|
user = relationship("User")
|
|
|
|
class AssetAssignment(Base):
|
|
__tablename__ = "asset_assignments"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), nullable=False)
|
|
organization_id = Column(Integer, ForeignKey("data.organizations.id"), nullable=False)
|
|
|
|
# ÚJ: Telephelyi hozzárendelés
|
|
branch_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.branches.id"), nullable=True)
|
|
|
|
assigned_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
released_at = Column(DateTime(timezone=True), nullable=True)
|
|
status = Column(String(30), default="active")
|
|
|
|
asset = relationship("Asset", back_populates="assignments")
|
|
organization = relationship("Organization")
|
|
branch = relationship("Branch") # Új kapcsolat
|
|
|
|
class AssetEvent(Base):
|
|
__tablename__ = "asset_events"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), nullable=False)
|
|
event_type = Column(String(50), nullable=False)
|
|
recorded_mileage = Column(Integer)
|
|
data = Column(JSONB, server_default=text("'{}'::jsonb"))
|
|
asset = relationship("Asset", back_populates="events")
|
|
|
|
class AssetCost(Base):
|
|
__tablename__ = "asset_costs"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
asset_id = Column(PG_UUID(as_uuid=True), ForeignKey("data.assets.id"), nullable=False)
|
|
organization_id = Column(Integer, ForeignKey("data.organizations.id"), nullable=False)
|
|
driver_id = Column(Integer, ForeignKey("data.users.id"), nullable=True)
|
|
cost_type = Column(String(50), nullable=False)
|
|
amount_local = Column(Numeric(18, 2), nullable=False)
|
|
currency_local = Column(String(3), nullable=False)
|
|
amount_eur = Column(Numeric(18, 2), nullable=True)
|
|
net_amount_local = Column(Numeric(18, 2))
|
|
vat_rate = Column(Numeric(5, 2))
|
|
exchange_rate_used = Column(Numeric(18, 6))
|
|
date = Column(DateTime(timezone=True), server_default=func.now())
|
|
mileage_at_cost = Column(Integer)
|
|
data = Column(JSONB, server_default=text("'{}'::jsonb"))
|
|
asset = relationship("Asset", back_populates="costs")
|
|
organization = relationship("Organization")
|
|
driver = relationship("User")
|
|
|
|
class ExchangeRate(Base):
|
|
__tablename__ = "exchange_rates"
|
|
__table_args__ = {"schema": "data"}
|
|
id = Column(Integer, primary_key=True)
|
|
base_currency = Column(String(3), default="EUR")
|
|
target_currency = Column(String(3), unique=True)
|
|
rate = Column(Numeric(18, 6), nullable=False)
|
|
|
|
class CatalogDiscovery(Base):
|
|
"""
|
|
Discovery tábla: Ide gyűjtjük a piaci 'neveket' (pl. Citroen C3).
|
|
A Robot innen indulva keresi meg az összes létező technikai variánst.
|
|
"""
|
|
__tablename__ = "catalog_discovery"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
make = Column(String(100), nullable=False, index=True)
|
|
model = Column(String(100), nullable=False, index=True)
|
|
vehicle_class = Column(String(50), index=True) # car, motorcycle, truck, stb.
|
|
source = Column(String(50)) # 'hasznaltauto', 'mobile.de'
|
|
status = Column(String(20), server_default=text("'pending'"), index=True)
|
|
attempts = Column(Integer, default=0)
|
|
last_attempt = Column(DateTime(timezone=True))
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
# EGYESÍTETT __table_args__
|
|
__table_args__ = (
|
|
UniqueConstraint('make', 'model', 'vehicle_class', name='_make_model_class_uc'),
|
|
{"schema": "data"}
|
|
) |