Add optional Firma/USt-IdNr. fields to checkout and profile
B2B checkout fields, split out from the e-invoicing migration and picked back up now that it's shipped. Both fields are independently optional, format-validated (shared regex in lib/vatId.ts, mirrored server-side in api/checkout and api/account/profile), persisted in the checkout draft, and saved as a customer profile default that pre-fills future checkouts. Order/customer snapshot fields land in a companion Payload backend commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,11 @@ export type CheckoutDraft = {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
// Optional B2B fields — see CheckoutContent.tsx's own comment on why
|
||||
// they sit here (right next to the Rechnungsadresse fields, not a
|
||||
// separate persisted concept).
|
||||
companyName: string;
|
||||
vatId: string;
|
||||
// Rechnungsadresse is always a plain street address now — no
|
||||
// deliveryMethod/packstationNumber/postNumber here, only on the
|
||||
// shipping* override fields below (see CheckoutContent.tsx).
|
||||
|
||||
@@ -199,6 +199,10 @@ export type CustomerAddress = {
|
||||
zip: string | null;
|
||||
city: string | null;
|
||||
country: string | null;
|
||||
// Optional B2B profile default — see Customers.ts's own comment. Prefills
|
||||
// /checkout's Firma/USt-IdNr. fields for a returning customer.
|
||||
companyName: string | null;
|
||||
vatId: string | null;
|
||||
};
|
||||
|
||||
export type CustomerProfile = CustomerSummary & CustomerAddress;
|
||||
@@ -217,6 +221,8 @@ type PayloadCustomerMe = {
|
||||
zip: string | null;
|
||||
city: string | null;
|
||||
country: string | null;
|
||||
companyName: string | null;
|
||||
vatId: string | null;
|
||||
cart: { product: number; productSlug: string; quantity: number; variantName: string | null }[] | null;
|
||||
};
|
||||
|
||||
@@ -243,6 +249,8 @@ export async function getCustomerProfile(token: string): Promise<CustomerProfile
|
||||
zip: u.zip,
|
||||
city: u.city,
|
||||
country: u.country,
|
||||
companyName: u.companyName,
|
||||
vatId: u.vatId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -259,6 +267,8 @@ export async function updateCustomerProfile(
|
||||
zip: string;
|
||||
city: string;
|
||||
country: string;
|
||||
companyName?: string;
|
||||
vatId?: string;
|
||||
},
|
||||
): Promise<{ ok: true } | { ok: false; reason: string }> {
|
||||
const res = await fetch(`${PAYLOAD_URL}/api/customers/${customerId}`, {
|
||||
|
||||
@@ -34,6 +34,10 @@ export type CreateOrderInput = {
|
||||
customerFirstName: string;
|
||||
customerLastName: string;
|
||||
customerEmail: string;
|
||||
// Optional B2B snapshot fields — see Orders.ts's own comment on why both
|
||||
// are independently optional.
|
||||
companyName?: string;
|
||||
vatId?: string;
|
||||
deliveryMethod: "address" | "packstation";
|
||||
street?: string;
|
||||
packstationNumber?: string;
|
||||
@@ -87,6 +91,8 @@ export async function createOrder(input: CreateOrderInput): Promise<CreatedOrder
|
||||
customerFirstName: input.customerFirstName,
|
||||
customerLastName: input.customerLastName,
|
||||
customerEmail: input.customerEmail,
|
||||
companyName: input.companyName,
|
||||
vatId: input.vatId,
|
||||
deliveryMethod: input.deliveryMethod,
|
||||
street: input.street,
|
||||
packstationNumber: input.packstationNumber,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Mirrors the backend's own USt-IdNr. validation exactly (Orders.ts/
|
||||
// Customers.ts/CompanySettings.ts in the Payload repo) — kept as a plain
|
||||
// client+server-safe helper here since this repo's frontend needs the same
|
||||
// check twice (checkout's instant client-side pattern + api/checkout's own
|
||||
// server-side re-validation, same "never trust the client" reasoning as
|
||||
// every other checkout field).
|
||||
const VAT_ID_PATTERN = /^[A-Z]{2}[A-Z0-9]{2,12}$/;
|
||||
|
||||
export function normalizeVatId(value: string): string {
|
||||
return value.toUpperCase().trim();
|
||||
}
|
||||
|
||||
export function isValidVatId(value: string): boolean {
|
||||
return VAT_ID_PATTERN.test(value);
|
||||
}
|
||||
Reference in New Issue
Block a user