merge conflict resolved

This commit is contained in:
marshal
2026-09-02 22:35:18 +00:00
376 changed files with 26459 additions and 2649 deletions

View File

@@ -76,9 +76,14 @@ export interface ETradeBusinessOption {
export interface CompanyRegistrationData {
/**
* The registered organization name — `ETradeCompanyInfo.BusinessName`, falling
* back to the licence's `TradeName`. Never the manager/owner's personal name;
* that is {@link managerName}.
* The selected licence's trade name — `ETradeBusinessInfo.TradeName`, falling
* back to the registered organization name (`ETradeCompanyInfo.BusinessName`)
* when eTrade leaves the licence's trade name blank. Never the manager/owner's
* personal name; that is {@link managerName}.
*
* NOT the legal entity name: a TIN often trades under a different name, and
* some hold several licences with different trade names. Anything that needs
* the registered name (tax/EIMS) must read `BusinessName` directly.
*/
companyName: string;
licenceNumber: string;

View File

@@ -765,6 +765,25 @@ export interface ICustomerTruckContainer {
containerNumber: string;
}
/**
* The truck-type vocabulary a customer picks from when self-hauling. The API
* validates against this exact list (`@IsIn`), the portal's dropdown renders it,
* and the bulk-upload template documents it — all three read this constant so a
* value the customer can type can never be one the API rejects.
*/
export const CUSTOMER_TRUCK_TYPES = [
"Flatbed",
"Container Chassis",
"Lowboy",
"Box Truck",
"Tipper",
] as const;
export type CustomerTruckType = (typeof CUSTOMER_TRUCK_TYPES)[number];
/** ISO 6346 container number: four letters then seven digits, e.g. ABCD1234567. */
export const ISO_CONTAINER_NUMBER = /^[A-Z]{4}\d{7}$/;
/** A customer self-haul truck on a booking, carrying 12 containers. */
export interface ICustomerTruck {
id: string;
@@ -776,6 +795,10 @@ export interface ICustomerTruck {
arrivedAt?: string | null;
departedAt?: string | null;
containers?: ICustomerTruckContainer[];
/** Bulk: planned tonnage this truck hauls. `numeric` — serialises as a string. */
plannedTons?: number | string | null;
/** Bulk PER_ITEM: planned item/piece count on this truck. */
plannedQuantity?: number | null;
}
/** Payload to add a customer self-haul truck (12 container numbers). */
@@ -783,7 +806,12 @@ export interface AddCustomerTruckPayload {
truckPlateNumber: string;
driverName: string;
truckType: string;
containerNumbers: string[];
/** Container bookings only — bulk trucks haul loose tonnage instead. */
containerNumbers?: string[];
/** Bulk: planned tonnage, drawn down against the booking's declared VGM. */
plannedTons?: number;
/** Bulk PER_ITEM: planned item/piece count. */
plannedQuantity?: number;
}
export interface IBooking extends BaseEntity {

View File

@@ -3,6 +3,7 @@ import type { BaseEntity } from "../common";
export * from "./support-chat";
export * from "./blocked-seat-revenue-loss";
export enum TicketStatus {
Reserved = "RESERVED",
Confirmed = "CONFIRMED",
@@ -38,9 +39,9 @@ export enum ScheduleStatus {
/**
* Why a /search leg (outbound or inbound) came back with zero bookable schedules.
* Priority order applied by the API when classifying: NoRoute > NoScheduleOnDate >
* Cancelled > PackageOnly > CheckinClosed > FullyBooked (see search.service.ts
* classifyEmptySearch). The frontend uses this to show a specific empty-state
* message instead of a generic "no trains available".
* Cancelled > PackageOnly > GroupBookingOnly > CheckinClosed > FullyBooked (see
* search.service.ts classifyEmptySearch). The frontend uses this to show a specific
* empty-state message instead of a generic "no trains available".
*/
export enum SearchEmptyReasonCode {
/** No route (in either direction) ever connects these two stations. */
@@ -51,6 +52,8 @@ export enum SearchEmptyReasonCode {
Cancelled = "CANCELLED",
/** Every schedule for this pair on this date is package-only (excluded from ticket search). */
PackageOnly = "PACKAGE_ONLY",
/** Every schedule for this pair on this date is reserved for staff group bookings (excluded from normal ticket search). */
GroupBookingOnly = "GROUP_BOOKING_ONLY",
/** A bookable schedule exists, but its check-in cutoff has already passed for every option. */
CheckinClosed = "CHECKIN_CLOSED",
/** A bookable, still-open schedule exists but has no seats left for the requested party. */