import { Entity, PrimaryGeneratedColumn, Column, Index, ManyToOne, JoinColumn, } from 'typeorm'; import { Viaje } from './viaje.entity'; /** * Tipo de Parada */ export enum TipoParada { RECOLECCION = 'RECOLECCION', ENTREGA = 'ENTREGA', ESCALA = 'ESCALA', } /** * Estado de la Parada */ export enum EstadoParada { PENDIENTE = 'PENDIENTE', EN_CAMINO = 'EN_CAMINO', LLEGADA = 'LLEGADA', EN_PROCESO = 'EN_PROCESO', COMPLETADA = 'COMPLETADA', OMITIDA = 'OMITIDA', } @Entity({ schema: 'transport', name: 'paradas_viaje' }) @Index('idx_parada_viaje', ['viajeId']) export class ParadaViaje { @PrimaryGeneratedColumn('uuid') id: string; @Column({ name: 'tenant_id', type: 'uuid' }) tenantId: string; @Column({ name: 'viaje_id', type: 'uuid' }) viajeId: string; @ManyToOne(() => Viaje) @JoinColumn({ name: 'viaje_id' }) viaje: Viaje; // Secuencia @Column({ type: 'int' }) secuencia: number; // Tipo de parada @Column({ type: 'enum', enum: TipoParada }) tipo: TipoParada; // Ubicación @Column({ type: 'text' }) direccion: string; @Column({ name: 'codigo_postal', type: 'varchar', length: 10, nullable: true }) codigoPostal: string; @Column({ type: 'varchar', length: 100, nullable: true }) ciudad: string; @Column({ type: 'varchar', length: 100, nullable: true }) estado: string; @Column({ type: 'decimal', precision: 10, scale: 7, nullable: true }) latitud: number; @Column({ type: 'decimal', precision: 10, scale: 7, nullable: true }) longitud: number; // Contacto @Column({ name: 'contacto_nombre', type: 'varchar', length: 200, nullable: true }) contactoNombre: string; @Column({ name: 'contacto_telefono', type: 'varchar', length: 30, nullable: true }) contactoTelefono: string; // Programación @Column({ name: 'hora_programada_llegada', type: 'timestamptz', nullable: true }) horaProgramadaLlegada: Date; @Column({ name: 'hora_programada_salida', type: 'timestamptz', nullable: true }) horaProgramadaSalida: Date; // Real @Column({ name: 'hora_real_llegada', type: 'timestamptz', nullable: true }) horaRealLlegada: Date; @Column({ name: 'hora_real_salida', type: 'timestamptz', nullable: true }) horaRealSalida: Date; // OTs asociadas @Column({ name: 'ots_ids', type: 'uuid', array: true, nullable: true }) otsIds: string[]; // Estado @Column({ name: 'estado_parada', type: 'enum', enum: EstadoParada, default: EstadoParada.PENDIENTE }) estadoParada: EstadoParada; // Observaciones @Column({ type: 'text', nullable: true }) observaciones: string; // Helper para calcular tiempo de permanencia get tiempoPermanenciaMinutos(): number | null { if (this.horaRealLlegada && this.horaRealSalida) { const diff = this.horaRealSalida.getTime() - this.horaRealLlegada.getTime(); return Math.round(diff / (1000 * 60)); } return null; } // Helper para verificar si está retrasada get estaRetrasada(): boolean { if (this.horaProgramadaLlegada && this.horaRealLlegada) { return this.horaRealLlegada > this.horaProgramadaLlegada; } return false; } }