fix: the direction for the yard

This commit is contained in:
ghost2023
2026-06-12 17:05:54 +03:00
parent 614b4ab16b
commit e075252639
5 changed files with 57 additions and 59 deletions

View File

@@ -70,7 +70,7 @@ export default function NewBookingPage() {
const destinationYard = form.watch("destinationYard");
const direction = useMemo(
() => getRouteDirection(originYard, destinationYard),
() => getRouteDirection(referenceData?.yard.find((y) => y.id === originYard), referenceData?.yard.find((y) => y.id === destinationYard)),
[originYard, destinationYard],
);
@@ -163,12 +163,7 @@ export default function NewBookingPage() {
: "WITHOUT_RETURN",
originYardId: findYardId(data.originYard),
destinationYardId: findYardId(data.destinationYard),
tradeDirection:
direction === "export"
? "EXPORT"
: direction === "domestic"
? "DOMESTIC"
: "IMPORT",
tradeDirection: direction!,
cargoTypeId: data.cargoType === "container" ? undefined : cargoTypeId,
cargoTotalWeightVgm: totalWeight,
isHazardous: data.isHazardous,

View File

@@ -2,15 +2,6 @@ import type { Freight } from "@edr/types";
import { DeepPartial, Path } from "react-hook-form";
import * as z from "zod";
export const ETHIOPIA_STATIONS = new Set<string>([
"Addis Ababa",
"Adama",
"Mojo",
"Awash",
"Mieso",
"Dire Dawa",
]);
export const MOCK_VALID_CONTRACTS = [
"EDR-2024-10001",
"EDR-2024-10002",
@@ -23,8 +14,9 @@ export const STEPS = [
{ id: 2, label: "Service Type & Mile", short: "Service" },
{ id: 3, label: "Route", short: "Route" },
{ id: 4, label: "Cargo Details", short: "Cargo" },
{ id: 5, label: "Documents", short: "Documents" },
{ id: 6, label: "Review & Submit", short: "Submit" },
{ id: 5, label: "Shipment Date", short: "Schedule" },
{ id: 6, label: "Documents", short: "Documents" },
{ id: 7, label: "Review & Submit", short: "Submit" },
] as const;
/**
@@ -108,6 +100,7 @@ export const bookingFormSchema = z
originYard: z.string().min(1, "Select an origin yard."),
destinationYard: z.string().min(1, "Select a destination yard."),
shippingLine: z.string(),
scheduledDate: z.string().min(1, "Select a shipment date."),
cargoType: z.enum(["container", "bulk"], "Select a cargo type."),
cargoWeight: z.string(),
freightType: z.string(), // parent group
@@ -235,6 +228,7 @@ export const initialBookingFormValues: DeepPartial<BookingFormValues> = {
originYard: "",
destinationYard: "",
shippingLine: "",
scheduledDate: "",
cargoWeight: "",
bulkCommoditytype: "",
isHazardous: false,
@@ -270,12 +264,11 @@ export const stepFields: Record<number, Array<Path<BookingFormValues>>> = {
"containers",
"consolidationEnabled",
],
5: ["documents"],
6: ["notes", "termsAccepted"],
5: ["scheduledDate"],
6: ["documents"],
7: ["notes", "termsAccepted"],
};
export type RouteDirection = "import" | "export" | "domestic" | null;
export interface ContainerConfig {
type: "20ft" | "40ft";
containerType: string;
@@ -296,35 +289,21 @@ export interface WagonCalcResult {
ft20Wagons: number;
}
export function genContractId(): string {
const yr = new Date().getFullYear();
const n = Math.floor(10000 + Math.random() * 90000);
return `EDR-DRAFT-${yr}-${n}`;
}
export function getRouteDirection(
origin: string,
dest: string,
): RouteDirection {
origin: Freight.BookingReferenceYard | null | undefined,
dest: Freight.BookingReferenceYard | null | undefined,
): Freight.ScheduleTradeDirection | null {
if (!origin || !dest) return null;
const oLocation = getStationLocation(origin);
const dLocation = getStationLocation(dest);
if (oLocation === "inside" && dLocation === "outside") return "export";
if (oLocation === "outside" && dLocation === "inside") return "import";
if (oLocation === "inside" && dLocation === "inside") return "domestic";
const oEth = ETHIOPIA_STATIONS.has(origin);
const dEth = ETHIOPIA_STATIONS.has(dest);
if (oEth && !dEth) return "export";
if (!oEth && dEth) return "import";
if (oEth && dEth) return "domestic";
return null;
if(origin.country === 'ethiopia' && dest.country === 'ethiopia') {
return 'DOMESTIC';
}
if(origin.country === 'ethiopia' && dest.country === 'djibouti') {
return 'IMPORT';
}
if(origin.country === 'djibouti' && dest.country === 'ethiopia') {
return 'EXPORT';
}
function getStationLocation(value: string): "inside" | "outside" | null {
const normalized = value.trim().toLowerCase();
if (normalized.startsWith("inside")) return "inside";
if (normalized.startsWith("outside")) return "outside";
return null;
}

View File

@@ -26,7 +26,7 @@ export function Step4Route({
const yardOptions = useMemo(() => {
if (!referenceData?.yard) return [];
return referenceData.yard.map((y) => ({ value: y.name, label: y.name }));
return referenceData.yard.map((y) => ({ value: y.id, label: y.name }));
}, [referenceData]);
const shippingLineOptions = useMemo(() => {
@@ -35,15 +35,40 @@ export function Step4Route({
}, [referenceData]);
const originData = useMemo(
() => yardOptions.filter((o) => o.value !== destinationYard),
() => {
return yardOptions.filter((o) => o.value !== destinationYard).filter((o) => {
const dest = referenceData?.yard.find((y) => y.id === destinationYard);
if(!dest) return true;
const origin = referenceData?.yard.find((y) => y.id === o.value);
// can't go from Djibouti to Djibouti
if(dest?.country === 'Djibouti' && origin?.country == 'Djibouti') return false;
return true;
});
},
[yardOptions, destinationYard],
);
console.log({yardOptions,originYard, destinationYard})
const destData = useMemo(
() => yardOptions.filter((o) => o.value !== originYard),
() => {
return yardOptions.filter((o) => o.value !== originYard).filter((d) => {
const origin = referenceData?.yard.find((y) => y.id === originYard);
if(!origin) return true;
const dest = referenceData?.yard.find((y) => y.id === d.value);
// can't go from Djibouti to Djibouti
// if(origin.country === 'Djibouti' && dest?.country == 'Djibouti') return false;
return true;
});
},
[yardOptions, originYard],
);
const direction = getRouteDirection(originYard, destinationYard);
const direction = getRouteDirection(referenceData?.yard.find((y) => y.id === originYard), referenceData?.yard.find((y) => y.name === destinationYard));
const directionStyle: Record<string, string> = {
export: "bg-sky-50 text-sky-800 border-sky-200",
@@ -57,7 +82,7 @@ export function Step4Route({
};
useEffect(() => {
if (direction === "domestic") {
if (direction === "DOMESTIC") {
form.setValue("shippingLine", "", { shouldDirty: true });
}
}, [direction]);
@@ -117,7 +142,7 @@ export function Step4Route({
</div>
)}
{direction && direction !== "domestic" && (
{direction && direction !== "DOMESTIC" && (
<Controller
name="shippingLine"
control={form.control}

View File

@@ -7,7 +7,6 @@ import {
BookingFormInputValues,
calcWagons,
type BookingFormValues,
type RouteDirection,
} from "./schema";
import {
AlertBox,
@@ -27,7 +26,7 @@ export function Step5CargoDetails({
isLoading,
}: {
form: BookingForm;
direction: RouteDirection;
direction: Freight.ScheduleTradeDirection;
referenceData?: Freight.BookingReferenceData;
isLoading?: boolean;
}) {
@@ -65,7 +64,7 @@ export function Step5CargoDetails({
vgm: number,
): string | null {
if (type === "20ft" && vgm > 0) {
const limit = direction === "export" ? 25 : 20;
const limit = direction === "EXPORT" ? 25 : 20;
if (vgm > limit) {
return `VGM ${vgm}t exceeds the ${limit}t ${direction ?? "standard"} limit for a 20ft container. An Overweight Surcharge will apply.`;
}
@@ -282,7 +281,7 @@ export function Step5CargoDetails({
val: "20ft" as const,
label: "20ft Container (TEU)",
limit:
direction === "export"
direction === "EXPORT"
? "Max 25t per container"
: "Max 20t per container",
},

View File

@@ -5,9 +5,9 @@ import {
BOOKING_DOCS_SETTING,
type BookingDocuments,
type BookingFormValues,
type RouteDirection,
} from "./schema";
import { StepHeader } from "./shared";
import type { Freight } from "@/types";
type BookingForm = UseFormReturn<BookingFormInputValues, any, BookingFormValues>;
@@ -18,7 +18,7 @@ export function Step8Review({
}: {
form: BookingForm;
setStep: (step: number) => void;
direction: RouteDirection;
direction: Freight.ScheduleTradeDirection;
}) {
const values = form.watch();
const errors = form.formState.errors;