mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Merge pull request #1183 from Tria-plc/freight_feature/usermanagement
feat(freight-web): restrict booking currency to ETB and portal ETB pa…
This commit is contained in:
@@ -276,9 +276,8 @@ export default function GlCreateBookingForm() {
|
||||
const [trainScheduleId, setTrainScheduleId] = useState("");
|
||||
const [contractRouteId, setContractRouteId] = useState<string | null>(null);
|
||||
const [notes, setNotes] = useState("");
|
||||
// The customer states the billing currency on their shipment request — GL
|
||||
// books in it. Intercity is always ETB (the API enforces this too).
|
||||
const [paymentCurrency, setPaymentCurrency] = useState<"USD" | "ETB">("USD");
|
||||
// ponytail: ETB-only for now — widen back to "USD" | "ETB" when multi-currency billing returns.
|
||||
const [paymentCurrency, setPaymentCurrency] = useState<"USD" | "ETB">("ETB");
|
||||
// What the containers carry — captured per booking (moved off the contract).
|
||||
const [cargoDescription, setCargoDescription] = useState("");
|
||||
const [containerLines, setContainerLines] = useState<ContainerLineDraft[]>([]);
|
||||
@@ -449,9 +448,6 @@ export default function GlCreateBookingForm() {
|
||||
}
|
||||
if (bookingRequest.contractRouteId)
|
||||
setContractRouteId(bookingRequest.contractRouteId);
|
||||
if (bookingRequest.paymentCurrency === "USD" || bookingRequest.paymentCurrency === "ETB") {
|
||||
setPaymentCurrency(bookingRequest.paymentCurrency);
|
||||
}
|
||||
if (bookingRequest.notes) setNotes(bookingRequest.notes);
|
||||
}, [bookingRequest, prefilled]);
|
||||
|
||||
@@ -1761,11 +1757,7 @@ export default function GlCreateBookingForm() {
|
||||
Billing currency
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mb={8}>
|
||||
{isIntercity
|
||||
? "Intercity shipments are invoiced in ETB."
|
||||
: bookingRequest?.paymentCurrency
|
||||
? "Requested by the customer on their shipment request."
|
||||
: "The contract is quoted in USD — pick the currency this shipment is invoiced in."}
|
||||
Shipments are invoiced in ETB.
|
||||
</Text>
|
||||
<CurrencySelector
|
||||
value={isIntercity ? "ETB" : paymentCurrency}
|
||||
|
||||
@@ -529,10 +529,7 @@ export default function NewBookingPage() {
|
||||
/>
|
||||
<Select
|
||||
label="Payment currency"
|
||||
data={[
|
||||
{ value: "ETB", label: "ETB — Birr" },
|
||||
{ value: "USD", label: "USD — Dollar" },
|
||||
]}
|
||||
data={[{ value: "ETB", label: "ETB — Birr" }]}
|
||||
value={paymentCurrency}
|
||||
onChange={(v) => setPaymentCurrency(v ?? "ETB")}
|
||||
/>
|
||||
|
||||
BIN
apps/edr-freight-web/portal/public/assets/cbe.png
Normal file
BIN
apps/edr-freight-web/portal/public/assets/cbe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 274 KiB |
@@ -25,17 +25,20 @@ interface ProviderOption {
|
||||
currencies: string[];
|
||||
accent: string;
|
||||
}
|
||||
|
||||
|
||||
// Only Telebirr, Waafi, CAC Bank and CBE bill payment are enabled for now.
|
||||
|
||||
// ponytail: ETB pays via CBE bill only for now — restore the Telebirr entry
|
||||
// ({ method: "TELEBIRR", currencies: ["ETB"] }) when mobile money returns.
|
||||
const PROVIDERS: ProviderOption[] = [
|
||||
{
|
||||
method: "TELEBIRR",
|
||||
label: "telebirr",
|
||||
description: "Ethiopian mobile money · ETB",
|
||||
logo: "/assets/telebirr.jpeg",
|
||||
currencies: ["ETB"],
|
||||
accent: "#0A6F4D",
|
||||
},
|
||||
// {
|
||||
// method: "TELEBIRR",
|
||||
// label: "telebirr",
|
||||
// description: "Ethiopian mobile money · ETB",
|
||||
// logo: "/assets/telebirr.jpeg",
|
||||
// currencies: ["ETB"],
|
||||
// accent: "#0A6F4D",
|
||||
// },
|
||||
{
|
||||
method: "WAAFI",
|
||||
label: "Waafi",
|
||||
@@ -55,7 +58,7 @@ const PROVIDERS: ProviderOption[] = [
|
||||
method: "CBE_BILL",
|
||||
label: "CBE bill payment",
|
||||
description: "Pay at any CBE branch, app or USSD · ETB",
|
||||
logo: "/assets/edr-logo.png",
|
||||
logo: "/assets/cbe.png",
|
||||
currencies: ["ETB"],
|
||||
accent: "#5B2D8C",
|
||||
},
|
||||
@@ -69,8 +72,8 @@ const OTP_LENGTH = 4;
|
||||
const isBillMethod = (method: PaymentMethod) => method === "CBE_BILL";
|
||||
|
||||
/**
|
||||
* Pick the provider that settles in the booking's currency. USD → Waafi,
|
||||
* ETB → Telebirr. Falls back to the first provider when unknown.
|
||||
* Pick the provider that settles in the booking's currency. USD → Waafi/CAC,
|
||||
* ETB → CBE bill. Falls back to the full list when unknown.
|
||||
*/
|
||||
function providersForCurrency(currency?: string | null): ProviderOption[] {
|
||||
const cur = currency?.trim().toUpperCase();
|
||||
@@ -190,7 +193,7 @@ export function PaymentMethodModal({
|
||||
onClose: () => void;
|
||||
/** Human-readable total, e.g. "ETB 12,500". */
|
||||
amountLabel?: string;
|
||||
/** Booking payment currency — drives which provider is shown (USD → Waafi, ETB → Telebirr). */
|
||||
/** Booking payment currency — drives which provider is shown (USD → Waafi/CAC, ETB → CBE bill). */
|
||||
currency?: string | null;
|
||||
onConfirm: (method: PaymentMethod, payerAccount?: string) => void;
|
||||
processing?: boolean;
|
||||
|
||||
@@ -157,8 +157,8 @@ function mapBookingToFormValues(
|
||||
isRefrigerated: booking.isRefrigerated ?? false,
|
||||
bulkHazardousQty: String(Number(booking.bulkHazardousQuantity ?? 0)),
|
||||
bulkReeferQty: String(Number(booking.bulkReeferQuantity ?? 0)),
|
||||
paymentCurrency:
|
||||
booking.paymentCurrency === "ETB" ? "ETB" : "USD",
|
||||
// ponytail: ETB-only for now — old USD drafts are re-billed in ETB on edit.
|
||||
paymentCurrency: "ETB",
|
||||
scheduledDate: booking.scheduledDate
|
||||
? new Date(booking.scheduledDate).toISOString().slice(0, 10)
|
||||
: "",
|
||||
|
||||
@@ -81,11 +81,7 @@ export const PAYMENT_CURRENCY_OPTIONS: Array<{
|
||||
label: string;
|
||||
description: string;
|
||||
}> = [
|
||||
{
|
||||
value: "USD",
|
||||
label: "USD",
|
||||
description: "US Dollar — international pricing and invoicing.",
|
||||
},
|
||||
// ponytail: ETB-only for now — re-add the USD option when multi-currency billing returns.
|
||||
{
|
||||
value: "ETB",
|
||||
label: "ETB",
|
||||
@@ -373,7 +369,7 @@ export const initialBookingFormValues: DeepPartial<BookingFormValues> = {
|
||||
previousContractRef: "",
|
||||
|
||||
serviceTypeId: "",
|
||||
paymentCurrency: "USD",
|
||||
paymentCurrency: "ETB",
|
||||
firstMile: {
|
||||
enabled: false,
|
||||
pickUpAddress: "",
|
||||
|
||||
@@ -299,7 +299,7 @@ export function Step8Review({
|
||||
<DetailRow label="Service" value={serviceType?.name ?? ""} />
|
||||
<DetailRow
|
||||
label="Payment currency"
|
||||
value={values.paymentCurrency ?? "USD"}
|
||||
value={values.paymentCurrency ?? "ETB"}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
@@ -281,7 +281,7 @@ function mapBookingToShipmentValues(
|
||||
}>;
|
||||
};
|
||||
const values: Partial<ShipmentFormInputValues> = {
|
||||
paymentCurrency: booking.paymentCurrency === "ETB" ? "ETB" : "USD",
|
||||
paymentCurrency: "ETB",
|
||||
withReturn: booking.equipmentReturn === "WITH_RETURN",
|
||||
cargoDescription: b.cargoFreeText ?? "",
|
||||
...(b.contractRouteId ? { contractRouteId: b.contractRouteId } : {}),
|
||||
@@ -390,11 +390,8 @@ function NewShipmentBookingForm({
|
||||
// Seed the equipment-return toggle from the contract; the customer can
|
||||
// still flip it per shipment.
|
||||
withReturn: contract.equipmentReturn === "WITH_RETURN",
|
||||
// The contract quotes USD; the customer bills this shipment in the
|
||||
// currency they pick here. Intercity is always ETB, so it is preset;
|
||||
// everything else starts empty so the customer picks deliberately
|
||||
// instead of silently inheriting USD.
|
||||
paymentCurrency: contract.tradeDirection === "DOMESTIC" ? "ETB" : "",
|
||||
// ponytail: ETB-only for now — preset since there is no other choice.
|
||||
paymentCurrency: "ETB",
|
||||
},
|
||||
resolver: zodResolver(
|
||||
createShipmentFormSchema({
|
||||
@@ -1313,8 +1310,7 @@ function ScheduleStep({
|
||||
<Box mb="lg">
|
||||
<StepLabel>Billing currency *</StepLabel>
|
||||
<Text fz={12.5} c="dimmed" mt={4} mb={10}>
|
||||
Your contract is quoted in USD. Pick the currency this shipment is
|
||||
invoiced in — the total is converted for you.
|
||||
Shipments are invoiced in ETB.
|
||||
</Text>
|
||||
<CurrencySelector
|
||||
value={field.value || ""}
|
||||
|
||||
@@ -10,18 +10,13 @@ export interface CurrencySelectorProps {
|
||||
error?: string;
|
||||
}
|
||||
|
||||
// ponytail: ETB-only for now — restore the USD entry when multi-currency billing returns.
|
||||
const OPTIONS = [
|
||||
{
|
||||
code: "USD",
|
||||
symbol: "$",
|
||||
name: "US Dollar",
|
||||
hint: "As quoted on the contract",
|
||||
},
|
||||
{
|
||||
code: "ETB",
|
||||
symbol: "Br",
|
||||
name: "Ethiopian Birr",
|
||||
hint: "Converted from the USD total",
|
||||
hint: "All shipments are invoiced in ETB",
|
||||
},
|
||||
] as const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user