This commit is contained in:
Marshal
2026-07-14 11:06:49 +00:00
parent 957a185a4d
commit 6d0cf50b4d
64 changed files with 4896 additions and 404 deletions

View File

@@ -1,13 +1,21 @@
import { BaseEntity } from '@edr/api-common';
import { CargoUnitOfMeasure } from '@edr/types';
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
import {
Column,
Entity,
Index,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
} from 'typeorm';
import { WagonType } from '../../wagon-types/entities/wagon-type.entity';
@Entity({ schema: 'freight', name: 'cargo_types' })
@Index(['isActive'])
@Index(['displayOrder'])
@Index(['parentGroupId'])
@Index(['wagonTypeId'])
@Index(['code'])
export class CargoType extends BaseEntity {
@Column({ name: 'code', type: 'varchar', length: 50, unique: true, default: '' })
@@ -28,17 +36,19 @@ export class CargoType extends BaseEntity {
unitOfMeasure?: CargoUnitOfMeasure | null;
/**
* Wagon type that carries this (bulk) cargo. Replaces the former hardcoded
* cargo-code → wagon-code map: train scheduling resolves the bulk wagon type
* through this FK. Nullable — grouping rows and container/legacy cargo never
* carry it; scheduling throws if a scheduled bulk cargo type leaves it unset.
* Wagon types that can carry this (bulk) cargo. Train scheduling resolves the
* bulk wagon type through this list, picking whichever type the schedule's
* train (or yard) actually has. Grouping rows and container/legacy cargo
* leave it empty; scheduling throws if a scheduled bulk cargo type has none.
*/
@Column({ name: 'wagon_type_id', type: 'uuid', nullable: true })
wagonTypeId?: string | null;
@ManyToOne(() => WagonType, { nullable: true, onDelete: 'RESTRICT' })
@JoinColumn({ name: 'wagon_type_id' })
wagonType?: WagonType | null;
@ManyToMany(() => WagonType)
@JoinTable({
name: 'cargo_type_wagon_types',
schema: 'freight',
joinColumn: { name: 'cargo_type_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'wagon_type_id', referencedColumnName: 'id' },
})
wagonTypes?: WagonType[];
@Column({ name: 'requires_director_approval', type: 'boolean', default: false })
requiresDirectorApproval!: boolean;

View File

@@ -1,12 +1,11 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
import { Column, Entity, Index, JoinTable, ManyToMany, OneToMany } from 'typeorm';
import { WeightLimitRule } from './weight-limit-rule.entity';
import { WagonType } from '../../wagon-types/entities/wagon-type.entity';
@Entity({ schema: 'freight', name: 'container_types' })
@Index(['code'])
@Index(['isActive'])
@Index(['wagonTypeId'])
export class ContainerType extends BaseEntity {
@Column({ name: 'code', type: 'varchar', length: 20, unique: true })
code!: string;
@@ -27,17 +26,19 @@ export class ContainerType extends BaseEntity {
isOpenTop!: boolean;
/**
* Wagon type that carries this container. Replaces the former hardcoded
* container wagon-code default (NW5): train scheduling resolves the container
* wagon type through this FK. Nullable; scheduling throws if a scheduled
* container type leaves it unset.
* Wagon types that can carry this container (e.g. a 20ft rides NX70 or NW5).
* Train scheduling resolves the container wagon type through this list,
* picking whichever type the schedule's train (or yard) actually has.
* Scheduling throws if a scheduled container type has none configured.
*/
@Column({ name: 'wagon_type_id', type: 'uuid', nullable: true })
wagonTypeId?: string | null;
@ManyToOne(() => WagonType, { nullable: true, onDelete: 'RESTRICT' })
@JoinColumn({ name: 'wagon_type_id' })
wagonType?: WagonType | null;
@ManyToMany(() => WagonType)
@JoinTable({
name: 'container_type_wagon_types',
schema: 'freight',
joinColumn: { name: 'container_type_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'wagon_type_id', referencedColumnName: 'id' },
})
wagonTypes?: WagonType[];
@Column({ name: 'is_active', type: 'boolean', default: true })
isActive!: boolean;