feat: implement pivot-currency model, rbac smart tokens & fix circular imports
This commit is contained in:
@@ -1,133 +1,128 @@
|
||||
import uuid
|
||||
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, JSON, Numeric, text
|
||||
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, JSON, Numeric, text, Text
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
|
||||
from sqlalchemy.sql import func
|
||||
from app.db.base_class import Base
|
||||
|
||||
class AssetCatalog(Base):
|
||||
"""Központi jármű katalógus (Admin/Bot által tölthető)"""
|
||||
__tablename__ = "vehicle_catalog"
|
||||
__table_args__ = {"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)
|
||||
year_from = Column(Integer)
|
||||
year_to = Column(Integer)
|
||||
vehicle_class = Column(String) # land, sea, air
|
||||
vehicle_class = Column(String)
|
||||
fuel_type = Column(String)
|
||||
engine_code = Column(String)
|
||||
|
||||
factory_data = Column(JSON, server_default=text("'{}'::jsonb"))
|
||||
assets = relationship("Asset", back_populates="catalog")
|
||||
|
||||
class Asset(Base):
|
||||
"""A Jármű Identitás (Digital Twin törzsadatok)"""
|
||||
__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)
|
||||
|
||||
catalog_id = Column(Integer, ForeignKey("data.vehicle_catalog.id"))
|
||||
|
||||
# Nemzetközi mutatók
|
||||
quality_index = Column(Numeric(3, 2), default=1.00)
|
||||
system_mileage = Column(Integer, default=0)
|
||||
mileage_unit = Column(String(10), default="km") # Nemzetközi: km, miles, hours
|
||||
|
||||
is_verified = Column(Boolean, default=False)
|
||||
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")
|
||||
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(JSON, server_default=text("'{}'::jsonb"))
|
||||
comment = Column(Text)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
asset = relationship("Asset", back_populates="reviews")
|
||||
|
||||
class AssetAssignment(Base):
|
||||
"""Birtoklás követése (Kié a jármű és mettől meddig)"""
|
||||
__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)
|
||||
|
||||
assigned_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
released_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
status = Column(String(30), default="active")
|
||||
notes = Column(String)
|
||||
|
||||
asset = relationship("Asset", back_populates="assignments")
|
||||
organization = relationship("Organization", back_populates="assets")
|
||||
|
||||
class AssetEvent(Base):
|
||||
"""Élettörténeti események (Szerviz, km-óra állások, balesetek)"""
|
||||
__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)
|
||||
event_date = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
event_type = Column(String(50), nullable=False)
|
||||
recorded_mileage = Column(Integer)
|
||||
description = Column(String)
|
||||
data = Column(JSON, server_default=text("'{}'::jsonb"))
|
||||
|
||||
asset = relationship("Asset", back_populates="events")
|
||||
|
||||
class AssetCost(Base):
|
||||
"""
|
||||
Költségkezelő modell: Bruttó/Nettó/ÁFA és deviza támogatás.
|
||||
"""
|
||||
__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)
|
||||
|
||||
cost_type = Column(String(50), nullable=False) # fuel, service, tax, insurance, toll
|
||||
|
||||
# Pénzügyi adatok
|
||||
amount = Column(Numeric(18, 2), nullable=False) # Bruttó összeg
|
||||
net_amount = Column(Numeric(18, 2)) # Nettó összeg
|
||||
vat_amount = Column(Numeric(18, 2)) # ÁFA érték
|
||||
vat_rate = Column(Numeric(5, 2)) # ÁFA kulcs (pl. 27.00)
|
||||
|
||||
# Nemzetközi deviza kezelés
|
||||
currency = Column(String(3), default="HUF") # Riportálási deviza
|
||||
original_currency = Column(String(3)) # Számla eredeti devizája
|
||||
exchange_rate_at_cost = Column(Numeric(18, 6)) # Rögzítéskori árfolyam
|
||||
|
||||
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())
|
||||
description = Column(String)
|
||||
invoice_id = Column(String)
|
||||
mileage_at_cost = Column(Integer)
|
||||
|
||||
data = Column(JSON, server_default=text("'{}'::jsonb"))
|
||||
|
||||
asset = relationship("Asset", back_populates="costs")
|
||||
|
||||
class ExchangeRate(Base):
|
||||
"""Napi árfolyamok tárolása (ECB/MNB adatok alapján)"""
|
||||
__tablename__ = "exchange_rates"
|
||||
__table_args__ = {"schema": "data"}
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
base_currency = Column(String(3), default="EUR")
|
||||
target_currency = Column(String(3), nullable=False)
|
||||
target_currency = Column(String(3), unique=True)
|
||||
rate = Column(Numeric(18, 6), nullable=False)
|
||||
rate_date = Column(DateTime(timezone=False), index=True)
|
||||
provider = Column(String(50), default="ECB")
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
rate_date = Column(DateTime, server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
Reference in New Issue
Block a user