mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-06 12:25:02 +00:00
add draft declaration
This commit is contained in:
@@ -301,8 +301,9 @@ export default function GlCreateBookingForm() {
|
||||
const [trainScheduleId, setTrainScheduleId] = useState("");
|
||||
const [contractRouteId, setContractRouteId] = useState<string | null>(null);
|
||||
const [notes, setNotes] = useState("");
|
||||
// ponytail: ETB-only for now — widen back to "USD" | "ETB" when multi-currency billing returns.
|
||||
const [paymentCurrency, setPaymentCurrency] = useState<"USD" | "ETB">("ETB");
|
||||
// IMPORT bookings pick ETB or USD — starts empty so the choice is
|
||||
// deliberate (required before pricing). Everything else is forced to ETB.
|
||||
const [paymentCurrency, setPaymentCurrency] = useState<"USD" | "ETB" | "">("");
|
||||
// What the containers carry — captured per booking (moved off the contract).
|
||||
const [cargoDescription, setCargoDescription] = useState("");
|
||||
const [containerLines, setContainerLines] = useState<ContainerLineDraft[]>([]);
|
||||
@@ -1022,8 +1023,21 @@ export default function GlCreateBookingForm() {
|
||||
partnerCargoDescription,
|
||||
]);
|
||||
|
||||
// Only IMPORT actually chooses — the rest bill ETB regardless of the state.
|
||||
const effectiveCurrency: "USD" | "ETB" =
|
||||
isImport && paymentCurrency ? paymentCurrency : "ETB";
|
||||
const currencyError =
|
||||
isImport && !paymentCurrency
|
||||
? "Select the billing currency for this booking."
|
||||
: undefined;
|
||||
|
||||
const formValid =
|
||||
cargoValid && !oddBlocksSubmit && !dateError && !routeError && !partnerError;
|
||||
cargoValid &&
|
||||
!oddBlocksSubmit &&
|
||||
!dateError &&
|
||||
!routeError &&
|
||||
!partnerError &&
|
||||
!currencyError;
|
||||
|
||||
/** The create-booking DTO from the current form state — shared by the
|
||||
* authoritative price preview and the actual submit so what GL confirms is
|
||||
@@ -1033,7 +1047,7 @@ export default function GlCreateBookingForm() {
|
||||
|
||||
const payload: Freight.CreateBookingUnderContractDto = {
|
||||
...(contractRouteId ? { contractRouteId } : {}),
|
||||
paymentCurrency,
|
||||
paymentCurrency: effectiveCurrency,
|
||||
// Intercity bookings carry no date — staff assign a passing train later.
|
||||
...(scheduledDate
|
||||
? { scheduledDate: new Date(scheduledDate).toISOString() }
|
||||
@@ -1100,7 +1114,7 @@ export default function GlCreateBookingForm() {
|
||||
if (!partner || !consolidationActive) return null;
|
||||
|
||||
const payload: Freight.CreateBookingUnderContractDto = {
|
||||
paymentCurrency,
|
||||
paymentCurrency: effectiveCurrency,
|
||||
...(scheduledDate
|
||||
? { scheduledDate: new Date(scheduledDate).toISOString() }
|
||||
: {}),
|
||||
@@ -2138,10 +2152,11 @@ export default function GlCreateBookingForm() {
|
||||
: "Shipments are invoiced in ETB."}
|
||||
</Text>
|
||||
<CurrencySelector
|
||||
value={isIntercity ? "ETB" : paymentCurrency}
|
||||
value={isImport ? paymentCurrency : "ETB"}
|
||||
onChange={setPaymentCurrency}
|
||||
disabled={isIntercity}
|
||||
disabled={!isImport}
|
||||
allowUsd={isImport}
|
||||
error={currencyError}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -1835,13 +1835,59 @@ function DraftDeclarationStep({
|
||||
);
|
||||
const [currency, setCurrency] = useState(clearance.draftDeclaration?.currency ?? "ETB");
|
||||
const [loading, setLoading] = useState(false);
|
||||
// OFF = don't send the customer a draft: the step is skipped, staff file the
|
||||
// real declaration directly, and duty & tax passes by default with it.
|
||||
const [sendDraft, setSendDraft] = useState(true);
|
||||
|
||||
const changeRequest = clearance.draftDeclarationChangeRequest;
|
||||
const existingFiles = clearance.draftDeclaration?.files ?? [];
|
||||
const replaceMode = existingFiles.length > 0;
|
||||
|
||||
if (!sendDraft && !replaceMode) {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Switch
|
||||
label="Send the customer a draft declaration"
|
||||
description="Off: skip this step — upload the customs declaration directly. Duty & tax is passed by default."
|
||||
checked={sendDraft}
|
||||
onChange={(e) => setSendDraft(e.currentTarget.checked)}
|
||||
/>
|
||||
<Button
|
||||
color="edr-green"
|
||||
variant="light"
|
||||
loading={loading}
|
||||
fullWidth
|
||||
onClick={async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await bookingsService.skipDraftDeclaration(bookingId);
|
||||
toast.success(
|
||||
"Draft declaration skipped — upload the customs declaration next. Duty & tax passed.",
|
||||
);
|
||||
onChanged?.();
|
||||
} catch (e) {
|
||||
toast.error(e instanceof Error ? e.message : "Failed");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Skip draft declaration
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
{!replaceMode ? (
|
||||
<Switch
|
||||
label="Send the customer a draft declaration"
|
||||
description="Off: skip this step — upload the customs declaration directly. Duty & tax is passed by default."
|
||||
checked={sendDraft}
|
||||
onChange={(e) => setSendDraft(e.currentTarget.checked)}
|
||||
/>
|
||||
) : null}
|
||||
{/* The customer sent this draft back — their words drive the
|
||||
correction, so they lead the step. */}
|
||||
{changeRequest ? (
|
||||
|
||||
Reference in New Issue
Block a user