feat(warehouses): record container vs bulk freight type

Nullable freight_type on the warehouse, null meaning it takes both.
No backfill: every existing warehouse is unrestricted today and
writing a value would narrow allocation behind the operator's back.
Reuses FREIGHT_TYPES from the booking entity rather than a third copy
of the same two values.
This commit is contained in:
Hagernesh
2026-08-28 15:04:39 +00:00
parent d4373dfbe4
commit ba79b36d90
7 changed files with 81 additions and 3 deletions

View File

@@ -13,8 +13,19 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import { api } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
import type { SaveWarehousePayload, Warehouse, WarehouseType } from '@/types/warehouse';
import { extractErrorMessage, lettersOnly, statusOptions, warehouseTypeOptions } from './options';
import type {
SaveWarehousePayload,
Warehouse,
WarehouseFreightType,
WarehouseType,
} from '@/types/warehouse';
import {
extractErrorMessage,
lettersOnly,
statusOptions,
warehouseFreightTypeOptions,
warehouseTypeOptions,
} from './options';
interface CreateWarehouseModalProps {
opened: boolean;
@@ -26,6 +37,7 @@ interface FormState {
name: string;
code: string;
type: WarehouseType;
freightType: WarehouseFreightType | null;
stationId: string | null;
locationName: string;
capacityWeight: number | '';
@@ -38,6 +50,7 @@ const emptyForm = (): FormState => ({
name: '',
code: '',
type: 'OPEN_WAREHOUSE',
freightType: null,
stationId: null,
locationName: '',
capacityWeight: '',
@@ -66,6 +79,7 @@ export function CreateWarehouseModal({ opened, onClose, warehouse }: CreateWareh
name: warehouse.name,
code: warehouse.code,
type: warehouse.type,
freightType: warehouse.freightType ?? null,
stationId: warehouse.stationId ?? null,
locationName: warehouse.locationName ?? '',
capacityWeight: warehouse.capacityWeight ?? '',
@@ -90,6 +104,7 @@ export function CreateWarehouseModal({ opened, onClose, warehouse }: CreateWareh
name: form.name.trim(),
code: form.code.trim(),
type: form.type,
freightType: form.freightType,
stationId: form.stationId ?? undefined,
locationName: form.locationName.trim() || undefined,
capacityWeight: form.capacityWeight === '' ? undefined : Number(form.capacityWeight),
@@ -142,6 +157,14 @@ export function CreateWarehouseModal({ opened, onClose, warehouse }: CreateWareh
/>
<Group grow>
<Select
label="Freight type"
placeholder="Both"
data={warehouseFreightTypeOptions}
value={form.freightType}
onChange={(value) => setForm((f) => ({ ...f, freightType: value as WarehouseFreightType | null }))}
clearable
/>
<Select
label="Type"
data={warehouseTypeOptions}

View File

@@ -1,4 +1,5 @@
import {
WAREHOUSE_FREIGHT_TYPES,
WAREHOUSE_TYPES,
WAREHOUSE_YARD_TYPES,
WAREHOUSE_ZONE_TYPES,
@@ -73,6 +74,7 @@ export const yardsForBooking = (
};
export const warehouseTypeOptions = toOptions(WAREHOUSE_TYPES);
export const warehouseFreightTypeOptions = toOptions(WAREHOUSE_FREIGHT_TYPES);
export const yardTypeOptions = toOptions(WAREHOUSE_YARD_TYPES);
export const zoneTypeOptions = toOptions(WAREHOUSE_ZONE_TYPES);
export const statusOptions = toOptions(WAREHOUSE_STATUSES);

View File

@@ -180,11 +180,16 @@ export interface Facility {
export type WarehouseFacility = Facility;
/** What a warehouse handles. Null = both. */
export const WAREHOUSE_FREIGHT_TYPES = ['CONTAINER', 'BULK'] as const;
export type WarehouseFreightType = (typeof WAREHOUSE_FREIGHT_TYPES)[number];
export interface Warehouse {
id: string;
name: string;
code: string;
type: WarehouseType;
freightType: WarehouseFreightType | null;
stationId: string | null;
facilityId: string | null;
facility?: Facility | null;
@@ -1043,6 +1048,7 @@ export interface SaveWarehousePayload {
name: string;
code: string;
type: WarehouseType;
freightType?: WarehouseFreightType | null;
stationId?: string;
facilityId?: string;
locationName?: string;