feat: add 11 digit vat

This commit is contained in:
Nathnael
2026-08-10 13:56:25 +00:00
parent ce57be252c
commit c24c93bcf3
5 changed files with 23 additions and 11 deletions

View File

@@ -36,13 +36,13 @@ export class UpdateProfileDto {
@IsTin({ message: "TIN must be exactly 10 digits" })
tin?: string;
// Ethiopian VAT registration numbers are 10 digits, the same shape as the
// TIN. Both portal forms enforce that; without it here the API happily stored
// whatever a stale client sent, and the two layers disagreed about what the
// column may hold.
// Ethiopian VAT registration numbers are 10 digits (the same shape as the
// TIN), but some are issued with an 11th. Both portal forms enforce the same
// range; without it here the API happily stored whatever a stale client sent,
// and the two layers disagreed about what the column may hold.
@IsOptional()
@IsString()
@Matches(/^\d{10}$/, { message: "VAT number must be exactly 10 digits" })
@Matches(/^\d{10,11}$/, { message: "VAT number must be 10 or 11 digits" })
vatNumber?: string;
// `fanNumber` is deliberately absent: the FAN is the Fayda number of the

View File

@@ -59,10 +59,22 @@ describe("VAT number", () => {
).toBeUndefined();
});
it("accepts eleven digits", () => {
expect(
errorFor(values({ vatNumber: "00123456789" }), "vatNumber"),
).toBeUndefined();
});
it("rejects twelve digits", () => {
expect(errorFor(values({ vatNumber: "001234567890" }), "vatNumber")).toBe(
"VAT number must be 10 or 11 digits",
);
});
// `.length(10)` used to pass this, so a ten-letter string reached the API.
it("rejects ten non-digits", () => {
expect(errorFor(values({ vatNumber: "ABCDEFGHIJ" }), "vatNumber")).toBe(
"VAT number must be exactly 10 digits",
"VAT number must be 10 or 11 digits",
);
});

View File

@@ -25,7 +25,7 @@ export const onboardingSchema = z.object({
vatNumber: z
.string()
.min(1, "VAT number is required")
.regex(/^\d{10}$/, "VAT number must be exactly 10 digits"),
.regex(/^\d{10,11}$/, "VAT number must be 10 or 11 digits"),
// The owner's passport number — the foreign-company identity credential
// (Fayda is an Ethiopian national ID). Required only for a foreign company;
// enforced in buildOnboardingSchema since that depends on `nationality`.

View File

@@ -51,7 +51,7 @@ export default function CompanyInfoStep({
index={1}
title="VAT number"
status={
watch("vatNumber")?.length === 10 && !errors.vatNumber
(watch("vatNumber")?.length ?? 0) >= 10 && !errors.vatNumber
? "done"
: "todo"
}
@@ -59,7 +59,7 @@ export default function CompanyInfoStep({
<TextInput
aria-label="VAT Number"
placeholder="0012345678"
maxLength={10}
maxLength={11}
error={errors.vatNumber?.message}
{...register("vatNumber")}
/>

View File

@@ -46,7 +46,7 @@ export const COMPANY_PROFILE_SCHEMA = z.object({
vatNumber: z
.string()
.min(1, "VAT number is required")
.regex(/^\d{10}$/, "VAT number must be exactly 10 digits"),
.regex(/^\d{10,11}$/, "VAT number must be 10 or 11 digits"),
ownerPassportNumber: z.string().optional(),
// Registration/address fields are eTrade-sourced — locked once eTrade
// supplies a value, editable only as an escape hatch when it doesn't
@@ -332,7 +332,7 @@ export default function TabCompanyProfile({
<TextInput
label="VAT Number"
placeholder="e.g. 0012345678"
maxLength={10}
maxLength={11}
error={errors.vatNumber?.message}
{...register("vatNumber")}
/>