Files
ATLAS/backend/app/models/conductor.py
FlotillasGPS Developer 51d78bacf4 FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con:
- Backend FastAPI con PostgreSQL/TimescaleDB
- Frontend React con TypeScript y TailwindCSS
- App movil React Native con Expo
- Soporte para dispositivos GPS, Meshtastic y celulares
- Video streaming en vivo con MediaMTX
- Geocercas, alertas, viajes y reportes
- Autenticacion JWT y WebSockets en tiempo real

Documentacion completa y guias de usuario incluidas.
2026-01-21 08:18:00 +00:00

90 lines
3.3 KiB
Python

"""
Modelo de Conductor para gestión de operadores de vehículos.
"""
from datetime import date, datetime
from sqlalchemy import Boolean, Date, DateTime, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.database import Base
from app.models.base import TimestampMixin
class Conductor(Base, TimestampMixin):
"""Modelo de conductor/operador de vehículo."""
__tablename__ = "conductores"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
nombre: Mapped[str] = mapped_column(String(100), nullable=False)
apellido: Mapped[str] = mapped_column(String(100), nullable=False)
telefono: Mapped[str | None] = mapped_column(String(20), nullable=True)
email: Mapped[str | None] = mapped_column(String(255), nullable=True, index=True)
# Documento de identidad
documento_tipo: Mapped[str | None] = mapped_column(String(20), nullable=True) # DNI, INE, etc.
documento_numero: Mapped[str | None] = mapped_column(String(50), nullable=True)
# Licencia de conducir
licencia_numero: Mapped[str | None] = mapped_column(String(50), nullable=True, unique=True)
licencia_tipo: Mapped[str | None] = mapped_column(String(20), nullable=True) # A, B, C, D, E
licencia_vencimiento: Mapped[date | None] = mapped_column(Date, nullable=True)
# Información personal
foto_url: Mapped[str | None] = mapped_column(Text, nullable=True)
fecha_nacimiento: Mapped[date | None] = mapped_column(Date, nullable=True)
direccion: Mapped[str | None] = mapped_column(Text, nullable=True)
contacto_emergencia: Mapped[str | None] = mapped_column(String(100), nullable=True)
telefono_emergencia: Mapped[str | None] = mapped_column(String(20), nullable=True)
# Información laboral
fecha_contratacion: Mapped[date | None] = mapped_column(Date, nullable=True)
numero_empleado: Mapped[str | None] = mapped_column(String(50), nullable=True)
# Estado
activo: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
notas: Mapped[str | None] = mapped_column(Text, nullable=True)
# Relaciones
vehiculos: Mapped[list["Vehiculo"]] = relationship(
"Vehiculo",
back_populates="conductor",
lazy="selectin",
)
viajes: Mapped[list["Viaje"]] = relationship(
"Viaje",
back_populates="conductor",
lazy="dynamic",
)
alertas: Mapped[list["Alerta"]] = relationship(
"Alerta",
back_populates="conductor",
lazy="dynamic",
)
cargas_combustible: Mapped[list["CargaCombustible"]] = relationship(
"CargaCombustible",
back_populates="conductor",
lazy="dynamic",
)
mensajes: Mapped[list["Mensaje"]] = relationship(
"Mensaje",
back_populates="conductor",
lazy="dynamic",
)
@property
def nombre_completo(self) -> str:
"""Retorna el nombre completo del conductor."""
return f"{self.nombre} {self.apellido}"
@property
def licencia_vigente(self) -> bool:
"""Verifica si la licencia está vigente."""
if not self.licencia_vencimiento:
return False
return self.licencia_vencimiento >= date.today()
def __repr__(self) -> str:
return f"<Conductor(id={self.id}, nombre='{self.nombre_completo}')>"