diff --git a/apps/edr-freight-web/backoffice/src/components/contracts/ContractClearanceReviewSection.tsx b/apps/edr-freight-web/backoffice/src/components/contracts/ContractClearanceReviewSection.tsx
index 7f84450f3..c660bb928 100644
--- a/apps/edr-freight-web/backoffice/src/components/contracts/ContractClearanceReviewSection.tsx
+++ b/apps/edr-freight-web/backoffice/src/components/contracts/ContractClearanceReviewSection.tsx
@@ -110,11 +110,12 @@ export function ContractClearanceReviewSection({
(clearance?.documents ?? []).filter((d) => d.uploadedBy === "customer"),
[clearance],
);
+ // GL output documents — anything not uploaded by the customer. The backend
+ // tags these `uploadedBy: 'gl'`; matching on "not customer" keeps it robust if
+ // that ever splits into gl_et / gl_dj.
const glDocs = useMemo(
() =>
- (clearance?.documents ?? []).filter(
- (d) => d.uploadedBy === "gl_et" || d.uploadedBy === "gl_dj",
- ),
+ (clearance?.documents ?? []).filter((d) => d.uploadedBy !== "customer"),
[clearance],
);
diff --git a/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceDetailPage.tsx b/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceDetailPage.tsx
index 1279177bf..19e2c8cb9 100644
--- a/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceDetailPage.tsx
+++ b/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceDetailPage.tsx
@@ -222,6 +222,11 @@ function ClearanceHero({
stats: { pct: number; approved: number; total: number };
}) {
const direction = contract?.tradeDirection ?? "—";
+ const serviceName = contract?.serviceType?.serviceName ?? null;
+ const customs =
+ contract?.serviceType?.includesCustoms ??
+ contract?.customsClearingEnabled ??
+ false;
const routes = [...(contract?.routes ?? [])].sort(
(a, b) => a.sortOrder - b.sortOrder,
);
@@ -253,16 +258,27 @@ function ClearanceHero({
>
{direction}
- }
- >
- Customs
-
+ {customs ? (
+ }
+ >
+ Customs
+
+ ) : (
+
+ No customs
+
+ )}
+ {serviceName && (
+
+ {serviceName}
+
+ )}
{origin}
diff --git a/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceListPage.tsx b/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceListPage.tsx
index 5bd321583..304e6a69a 100644
--- a/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceListPage.tsx
+++ b/apps/edr-freight-web/backoffice/src/pages/contracts/ContractClearanceListPage.tsx
@@ -54,6 +54,8 @@ interface ClearanceRow {
originLabel: string;
destinationLabel: string;
contractKind: string;
+ serviceTypeName: string;
+ customs: boolean;
status: string;
/** true once GL has finalized clearance — customer now books in the portal. */
ready: boolean;
@@ -84,11 +86,32 @@ function toClearanceRow(contract: Freight.IContract): ClearanceRow {
originLabel: yardLabel(first?.originYard),
destinationLabel: yardLabel(last?.destinationYard),
contractKind: contract.contractKind,
+ serviceTypeName: contract.serviceType?.serviceName ?? "—",
+ customs:
+ contract.serviceType?.includesCustoms ?? contract.customsClearingEnabled,
status: contract.status,
ready: contract.status === "CLEARANCE_READY_FOR_BOOKING",
};
}
+function CustomsBadge({ customs }: { customs: boolean }) {
+ return customs ? (
+ }
+ >
+ Customs
+
+ ) : (
+
+ No customs
+
+ );
+}
+
function DirectionIcon({ direction }: { direction: string }) {
const isImport = direction === "IMPORT";
const Icon = isImport ? Truck : ShipWheel;
@@ -248,6 +271,21 @@ export default function ContractClearanceListPage() {
),
},
+ {
+ id: "service",
+ header: () => Service,
+ cell: ({ row }) => {
+ const r = row.original;
+ return (
+
+
+ {r.serviceTypeName}
+
+
+
+ );
+ },
+ },
{
id: "status",
header: () => Status,
@@ -545,6 +583,13 @@ function ClearanceCard({
{row.contractKind === "GENERAL" ? "General" : "One-time"}
+
+
+
+ {row.serviceTypeName}
+
+
+
);
}
diff --git a/packages/types/src/freight/contracts.ts b/packages/types/src/freight/contracts.ts
index 331da7990..39e032bfb 100644
--- a/packages/types/src/freight/contracts.ts
+++ b/packages/types/src/freight/contracts.ts
@@ -230,7 +230,7 @@ export interface ContractClearanceDocument {
fileKey: string;
label: string;
required: boolean;
- uploadedBy: "customer" | "gl_et" | "gl_dj";
+ uploadedBy: "customer" | "gl" | "gl_et" | "gl_dj";
phase: ContractDocPhase;
settingCode: string;
file: { id: string; name: string; url: string } | null;
@@ -406,6 +406,14 @@ export interface IContract extends BaseEntity {
freightType: ContractFreightType;
serviceTypeId: string;
+ /** Loaded service-type relation (queue + detail responses include it). */
+ serviceType?: {
+ id: string;
+ code: string;
+ serviceName: string;
+ canBeBookedAlone: boolean;
+ includesCustoms: boolean;
+ } | null;
paymentCurrency: string;
customsClearingEnabled: boolean;
customsClearingAgent?: string | null;