import { BaseEntity } from '@edr/api-common'; import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm'; import type { Freight } from '@edr/types'; import { Contract } from './contract.entity'; /** * A customer's request to ship under a GENERAL customs (Path B) contract. The * customer cannot book directly; they submit the date + quantities here, Global * Logistics reviews the queue, then creates the booking on their behalf — after * which per-booking customs clearance begins. ONE_TIME contracts do not use this * (they keep contract-level clearance). See plan: per-booking clearance. */ @Entity({ schema: 'freight', name: 'booking_requests' }) @Index(['contractId']) @Index(['status']) @Index(['contractId', 'status']) export class BookingRequest extends BaseEntity { @Column({ name: 'reference', type: 'varchar', length: 40, default: '' }) reference!: string; @Column({ name: 'contract_id', type: 'uuid' }) contractId!: string; @ManyToOne(() => Contract, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'contract_id' }) contract?: Contract; @Column({ name: 'requested_by_user_id', type: 'uuid', nullable: true }) requestedByUserId?: string | null; @Column({ name: 'contract_route_id', type: 'uuid', nullable: true }) contractRouteId?: string | null; /** Customer's preferred shipment day — informational; GL sets the binding date. */ @Column({ name: 'scheduled_date', type: 'timestamptz', nullable: true }) scheduledDate?: Date | null; @Column({ name: 'status', type: 'varchar', length: 16, default: 'PENDING' }) status!: Freight.BookingRequestStatus; /** Requested quantities (container lines or one bulk line) — no per-unit data. */ @Column({ name: 'requested_lines', type: 'jsonb', default: () => "'{}'::jsonb" }) requestedLines!: Freight.RequestedShipmentLines; @Column({ name: 'notes', type: 'text', nullable: true }) notes?: string | null; /** Set when GL accepts the request and creates the booking. */ @Column({ name: 'created_booking_id', type: 'uuid', nullable: true }) createdBookingId?: string | null; @Column({ name: 'reviewed_by_staff_id', type: 'uuid', nullable: true }) reviewedByStaffId?: string | null; @Column({ name: 'reviewed_at', type: 'timestamptz', nullable: true }) reviewedAt?: Date | null; @Column({ name: 'review_note', type: 'text', nullable: true }) reviewNote?: string | null; }