import { BaseEntity } from '@edr/api-common'; import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm'; import { ContainerType } from '../../rule-engine/entities/container-type.entity'; import { WeightLimitRule } from '../../rule-engine/entities/weight-limit-rule.entity'; import { Booking } from './booking.entity'; import { BookingContainerUnit } from './booking-container-unit.entity'; @Entity({ schema: 'freight', name: 'booking_container' }) @Index(['bookingId']) @Index(['isOverweight']) export class BookingContainer extends BaseEntity { @Column({ name: 'booking_id', type: 'uuid' }) bookingId!: string; @ManyToOne(() => Booking, (b) => b.bookingContainers, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'booking_id' }) booking?: Booking; @Column({ name: 'container_type_id', type: 'uuid', nullable: true }) containerTypeId?: string | null; @ManyToOne(() => ContainerType, { nullable: true }) @JoinColumn({ name: 'container_type_id' }) containerType?: ContainerType | null; @Column({ name: 'container_number', type: 'varchar', length: 64, nullable: true }) containerNumber?: string | null; /** Contract container size this line covers (20ft | 40ft). Null for legacy rows. */ @Column({ name: 'container_size', type: 'varchar', length: 10, nullable: true }) containerSize?: string | null; @Column({ name: 'quantity', type: 'smallint' }) quantity!: number; /** How many units of this line are hazardous (≤ quantity). */ @Column({ name: 'hazardous_quantity', type: 'smallint', default: 0 }) hazardousQuantity!: number; /** How many units of this line are refrigerated (≤ quantity). */ @Column({ name: 'reefer_quantity', type: 'smallint', default: 0 }) reeferQuantity!: number; /** How many units of this line ship with empty-container return (≤ quantity). */ @Column({ name: 'return_quantity', type: 'smallint', default: 0 }) returnQuantity!: number; @Column({ name: 'vgm_per_unit_tons', type: 'numeric', precision: 10, scale: 3 }) vgmPerUnitTons!: number; @Column({ name: 'total_vgm_tons', type: 'numeric', precision: 12, scale: 3 }) totalVgmTons!: number; @Column({ name: 'wagons_required', type: 'numeric', precision: 6, scale: 2 }) wagonsRequired!: number; @Column({ name: 'weight_limit_rule_id', type: 'uuid', nullable: true }) weightLimitRuleId?: string | null; @ManyToOne(() => WeightLimitRule, { nullable: true }) @JoinColumn({ name: 'weight_limit_rule_id' }) weightLimitRule?: WeightLimitRule | null; @Column({ name: 'is_overweight', type: 'boolean', default: false }) isOverweight!: boolean; @Column({ name: 'overweight_excess_tons', type: 'numeric', precision: 10, scale: 3, nullable: true }) overweightExcessTons?: number | null; /** The physical containers under this line — each with its own number + VGM. */ @OneToMany(() => BookingContainerUnit, (u) => u.bookingContainer) units?: BookingContainerUnit[]; }