- 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>
125 lines
3.1 KiB
TypeScript
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;
|
|
}
|
|
}
|