diff --git a/apps/edr-freight-web/backoffice/src/pages/bookings/NewBookingPage.tsx b/apps/edr-freight-web/backoffice/src/pages/bookings/NewBookingPage.tsx index e685a3cf4..690da9998 100644 --- a/apps/edr-freight-web/backoffice/src/pages/bookings/NewBookingPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/bookings/NewBookingPage.tsx @@ -180,8 +180,10 @@ export default function NewBookingPage() { const queryClient = useQueryClient(); const [isGovernment, setIsGovernment] = useState(false); - const [governmentInstitution, setGovernmentInstitution] = useState(""); const [companyId, setCompanyId] = useState(null); + // Government bookings bill to a real government company + an explicit profile. + const [govCompanyId, setGovCompanyId] = useState(null); + const [govProfileId, setGovProfileId] = useState(null); const [freightType, setFreightType] = useState("CONTAINER"); const [originYardId, setOriginYardId] = useState(null); const [destinationYardId, setDestinationYardId] = useState(null); @@ -220,6 +222,42 @@ export default function NewBookingPage() { label: c.name || c.email || c.tin || c.id, })); + // Active government companies (kind=government) the booking can bill to. + const { data: govCompaniesPage, isLoading: govCompaniesLoading } = useQuery({ + queryKey: ["companies", "government", "active"], + queryFn: () => + customersService.list({ + page: 1, + pageSize: 1000, + kind: "government", + status: "active", + }), + enabled: isGovernment, + }); + + const govCompanies = govCompaniesPage?.items ?? []; + const govCompanyOptions = govCompanies.map((c) => ({ + value: c.id, + label: c.name || c.tin || c.id, + })); + + // Profiles (importer/exporter) of the chosen government company — the booking + // must link to one explicitly. + const selectedGovCompany = govCompanies.find((c) => c.id === govCompanyId); + const govProfileOptions = (selectedGovCompany?.companyProfiles ?? []) + .filter((p) => p.status === "active") + .map((p) => ({ + value: p.id, + label: `${p.type === "importer" ? "Import" : p.type === "exporter" ? "Export" : p.type}${ + p.reference ? ` — ${p.reference}` : "" + }`, + })); + + // Reset the chosen profile when the government company changes. + useEffect(() => { + setGovProfileId(null); + }, [govCompanyId]); + // Day-level pool: fetch only the days that have a departure on the route (no // train, no capacity). The batch engine assigns the train after booking. const { data: availableDays, isLoading: daysLoading } = useQuery( @@ -306,7 +344,7 @@ export default function NewBookingPage() { Boolean(tradeDirection) && Boolean(serviceTypeId) && departureSatisfied && - (isGovernment ? governmentInstitution.trim().length >= 2 : Boolean(companyId)) && + (isGovernment ? Boolean(govCompanyId && govProfileId) : Boolean(companyId)) && (freightType === "BULK" ? Boolean(cargoTypeId) && bulkWeight > 0 : allLinesValid); @@ -320,8 +358,8 @@ export default function NewBookingPage() { mutationFn: () => bookingsService.create({ isGovernment, - governmentInstitution: isGovernment ? governmentInstitution : undefined, - companyId: isGovernment ? undefined : companyId || undefined, + companyId: isGovernment ? govCompanyId || undefined : companyId || undefined, + companyProfileId: isGovernment ? govProfileId || undefined : undefined, freightType, contractType: "NEW", equipmentReturn, @@ -390,18 +428,37 @@ export default function NewBookingPage() { setIsGovernment(e.currentTarget.checked)} /> {isGovernment ? ( - setGovernmentInstitution(e.currentTarget.value)} - required - /> + + + ) : (