From c1787fd45c20ab59afdc4def021d1dc23c7a31a8 Mon Sep 17 00:00:00 2001 From: bloodyowl Date: Tue, 22 Aug 2023 16:31:39 +0200 Subject: [PATCH] Fix rules for TIN --- .../src/components/MembershipDetailEditor.tsx | 70 ++++++++++++++----- .../src/components/NewMembershipWizard.tsx | 66 +++++++++++------ clients/banking/src/locales/en.json | 1 + .../src/pages/AccountDetailsSettingsPage.tsx | 19 +++-- clients/banking/src/utils/validations.ts | 19 ----- 5 files changed, 112 insertions(+), 63 deletions(-) diff --git a/clients/banking/src/components/MembershipDetailEditor.tsx b/clients/banking/src/components/MembershipDetailEditor.tsx index b9ed6ea6b..7497461cf 100644 --- a/clients/banking/src/components/MembershipDetailEditor.tsx +++ b/clients/banking/src/components/MembershipDetailEditor.tsx @@ -9,7 +9,9 @@ import { useUrqlMutation } from "@swan-io/lake/src/hooks/useUrqlMutation"; import { showToast } from "@swan-io/lake/src/state/toasts"; import { CountryPicker } from "@swan-io/shared-business/src/components/CountryPicker"; import { GMapAddressSearchInput } from "@swan-io/shared-business/src/components/GMapAddressSearchInput"; +import { TaxIdentificationNumberInput } from "@swan-io/shared-business/src/components/TaxIdentificationNumberInput"; import { CountryCCA3, allCountries } from "@swan-io/shared-business/src/constants/countries"; +import { validateIndividualTaxNumber } from "@swan-io/shared-business/src/utils/validation"; import dayjs from "dayjs"; import { useState } from "react"; import { StyleSheet, View } from "react-native"; @@ -30,7 +32,6 @@ import { validateBirthdate, validateName, validateRequired, - validateTaxIdentificationNumber, } from "../utils/validations"; import { MembershipCancelConfirmationModal } from "./MembershipCancelConfirmationModal"; import { MembershipInvitationLinkModal } from "./MembershipInvitationLinkModal"; @@ -188,11 +189,31 @@ export const MembershipDetailEditor = ({ initialValue: editingAccountMembership.taxIdentificationNumber ?? "", strategy: "onBlur", validate: (value, { getFieldState }) => { - return match({ accountCountry, residencyAddressCountry: getFieldState("country").value }) + return match({ + accountCountry, + country: getFieldState("country").value, + canViewAccount: editingAccountMembership.canViewAccount, + canInitiatePayment: editingAccountMembership.canInitiatePayments, + }) .with( - { accountCountry: "DEU", residencyAddressCountry: "DEU" }, { accountCountry: "NLD" }, - () => validateTaxIdentificationNumber(value), + P.intersection( + { accountCountry: "DEU", country: "DEU" }, + P.union( + { + canViewAccount: true, + }, + { canInitiatePayment: true }, + ), + ), + ({ accountCountry }) => + combineValidators( + validateRequired, + validateIndividualTaxNumber(accountCountry), + )(value), + ) + .with({ accountCountry: "DEU" }, { accountCountry: "NLD" }, ({ accountCountry }) => + validateIndividualTaxNumber(accountCountry)(value), ) .otherwise(() => {}); }, @@ -727,21 +748,36 @@ export const MembershipDetailEditor = ({ .with( { accountCountry: "DEU", country: "DEU" }, { accountCountry: "NLD" }, - () => ( + ({ accountCountry, country }) => ( {({ value, valid, error, onChange }) => ( - ( - - )} + true) + .with( + P.intersection( + { accountCountry: "DEU", country: "DEU" }, + P.union( + { + canViewAccount: true, + }, + { canInitiatePayment: true }, + ), + ), + () => true, + ) + .otherwise(() => false)} /> )} diff --git a/clients/banking/src/components/NewMembershipWizard.tsx b/clients/banking/src/components/NewMembershipWizard.tsx index 52081c561..fd6dd2f76 100644 --- a/clients/banking/src/components/NewMembershipWizard.tsx +++ b/clients/banking/src/components/NewMembershipWizard.tsx @@ -138,12 +138,10 @@ export const NewMembershipWizard = ({ const [memberAddition, addMember] = useUrqlMutation(AddAccountMembershipDocument); const steps: Step[] = match({ accountCountry, partiallySavedValues }) - .with( - { accountCountry: "DEU" }, - { accountCountry: "NLD" }, - { partiallySavedValues: { canInitiatePayments: true, canViewAccount: true } }, - () => ["Informations" as const, "Address" as const], - ) + .with({ accountCountry: "DEU" }, { accountCountry: "NLD" }, () => [ + "Informations" as const, + "Address" as const, + ]) .otherwise(() => ["Informations" as const]); const { Field, FieldsListener, setFieldValue, submitForm } = useForm({ @@ -213,13 +211,19 @@ export const NewMembershipWizard = ({ initialValue: partiallySavedValues?.addressLine1 ?? "", validate: (value, { getFieldState }) => { return match({ + accountCountry, canViewAccount: getFieldState("canViewAccount").value, canInitiatePayments: getFieldState("canInitiatePayments").value, }) - .with({ canViewAccount: true }, { canInitiatePayments: true }, () => { - const validate = combineValidators(validateRequired, validateAddressLine); - return validate(value); - }) + .with( + { accountCountry: "NLD" }, + { canViewAccount: true }, + { canInitiatePayments: true }, + () => { + const validate = combineValidators(validateRequired, validateAddressLine); + return validate(value); + }, + ) .otherwise(() => { return validateAddressLine(value); }); @@ -229,12 +233,18 @@ export const NewMembershipWizard = ({ initialValue: partiallySavedValues?.postalCode ?? "", validate: (value, { getFieldState }) => { return match({ + accountCountry, canViewAccount: getFieldState("canViewAccount").value, canInitiatePayments: getFieldState("canInitiatePayments").value, }) - .with({ canViewAccount: true }, { canInitiatePayments: true }, () => { - return validateRequired(value); - }) + .with( + { accountCountry: "NLD" }, + { canViewAccount: true }, + { canInitiatePayments: true }, + () => { + return validateRequired(value); + }, + ) .otherwise(() => undefined); }, }, @@ -242,12 +252,18 @@ export const NewMembershipWizard = ({ initialValue: partiallySavedValues?.city ?? "", validate: (value, { getFieldState }) => { return match({ + accountCountry, canViewAccount: getFieldState("canViewAccount").value, canInitiatePayments: getFieldState("canInitiatePayments").value, }) - .with({ canViewAccount: true }, { canInitiatePayments: true }, () => { - return validateRequired(value); - }) + .with( + { accountCountry: "NLD" }, + { canViewAccount: true }, + { canInitiatePayments: true }, + () => { + return validateRequired(value); + }, + ) .otherwise(() => undefined); }, }, @@ -255,12 +271,18 @@ export const NewMembershipWizard = ({ initialValue: partiallySavedValues?.country ?? accountCountry ?? "FRA", validate: (value, { getFieldState }) => { return match({ + accountCountry, canViewAccount: getFieldState("canViewAccount").value, canInitiatePayments: getFieldState("canInitiatePayments").value, }) - .with({ canViewAccount: true }, { canInitiatePayments: true }, () => { - return validateRequired(value); - }) + .with( + { accountCountry: "NLD" }, + { canViewAccount: true }, + { canInitiatePayments: true }, + () => { + return validateRequired(value); + }, + ) .otherwise(() => undefined); }, }, @@ -276,12 +298,10 @@ export const NewMembershipWizard = ({ }) .with( P.intersection( - P.union( - { accountCountry: "DEU", residencyAddressCountry: "DEU" }, - { accountCountry: "NLD" }, - ), + P.union({ accountCountry: "DEU", residencyAddressCountry: "DEU" }), P.union({ canViewAccount: true }, { canInitiatePayments: true }), ), + { accountCountry: "NLD" }, () => combineValidators( validateRequired, diff --git a/clients/banking/src/locales/en.json b/clients/banking/src/locales/en.json index 973c40f52..f1ac06d33 100644 --- a/clients/banking/src/locales/en.json +++ b/clients/banking/src/locales/en.json @@ -61,6 +61,7 @@ "accountDetails.settings.contractsDescription": "For your convenience, here are copies of your contracts:", "accountDetails.settings.language": "Official document language", "accountDetails.settings.languageDescription": "Choose the language you want to be used for official documents such as account statements and bank details.", + "accountDetails.settings.legalRepresentativeTaxIdentificationNumber": "Legal Representative Tax Identification Number", "accountDetails.settings.partnershipConditions": "{projectName} partnership conditions", "accountDetails.settings.save": "Save", "accountDetails.settings.tab": "Settings", diff --git a/clients/banking/src/pages/AccountDetailsSettingsPage.tsx b/clients/banking/src/pages/AccountDetailsSettingsPage.tsx index 9eed4d37d..b5765c508 100644 --- a/clients/banking/src/pages/AccountDetailsSettingsPage.tsx +++ b/clients/banking/src/pages/AccountDetailsSettingsPage.tsx @@ -136,9 +136,12 @@ export const AccountDetailsSettingsPage = ({ taxIdentificationNumber: { initialValue: holderInfo?.taxIdentificationNumber ?? "", sanitize: value => value.trim(), - validate: isCompany - ? validateCompanyTaxNumber(accountCountry) - : validateIndividualTaxNumber(accountCountry), + validate: + account?.country === "NLD" + ? combineValidators(validateRequired, validateIndividualTaxNumber(accountCountry)) + : isCompany + ? validateCompanyTaxNumber(accountCountry) + : validateIndividualTaxNumber(accountCountry), }, }); @@ -168,6 +171,7 @@ export const AccountDetailsSettingsPage = ({ const shouldEditTaxIdentificationNumber = (account.country === "DEU" && account.holder.residencyAddress.country === "DEU") || account.country === "NLD"; + const isTaxIdentificationRequired = account.country === "NLD"; const tcuUrl = account.holder.onboarding?.tcuUrl; @@ -235,6 +239,11 @@ export const AccountDetailsSettingsPage = ({ {({ error, onBlur, onChange, valid, value }) => ( )} @@ -252,7 +262,8 @@ export const AccountDetailsSettingsPage = ({ )} {shouldEditTaxIdentificationNumber && - isNullishOrEmpty(holderInfo?.taxIdentificationNumber) && ( + isNullishOrEmpty(holderInfo?.taxIdentificationNumber) && + !isTaxIdentificationRequired && ( <> = value => { } }; -export const validateTaxIdentificationNumber: Validator = value => { - if (!value) { - return t("common.form.required"); - } - if (value.length !== 11 && value.length !== 10) { - return t("common.form.invalidTaxIdentificationNumber"); - } -}; - -export const validateIndividualTaxNumber: Validator = value => { - if (!value) { - return; - } - // accept 11 digits - if (!/^\d{11}$/.test(value)) { - return t("common.form.invalidTaxIdentificationNumber"); - } -}; - export const validateAccountNameLength: Validator = value => { const maxLength = 256; if (value.length > maxLength) {