erp-transportistas-backend-v2/src/modules/viajes/entities/parada-viaje.entity.ts
Adrian Flores Cortes 99d18bb340 feat(entities): Complete viajes entities and adapt inventory/financial
- Add Viaje entity with transport-specific workflow states
- Add ParadaViaje entity for multi-stop support
- Add Pod entity for Proof of Delivery
- Adapt inventory/product.entity with TipoRefaccion for fleet parts
- Adapt financial/account.entity with TipoCuentaTransporte and TipoCentroCosto
- Update index exports for all modified modules

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:38:08 -06:00

125 lines
3.1 KiB
TypeScript

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;
}
}