Files
edr-platform/apps/edr-freight-api/src/modules/contracts/entities/booking-request.entity.ts
Marshal 0f7cac2b68 add booking request functionality for GENERAL customs contracts
- Create migration for booking_requests table with necessary fields and indexes.
- Implement BookingRequestRepository for database operations related to booking requests.
- Develop BookingRequestService to handle business logic for submitting, accepting, rejecting, and canceling booking requests.
- Create DTOs for creating booking requests and reviewing them.
- Define BookingRequest entity to map to the booking_requests table.
- Add UI components for managing shipment requests, including detail and list pages.
- Implement OperationDatePicker component for selecting available shipment days.
2026-06-29 09:30:44 +00:00

62 lines
2.4 KiB
TypeScript

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