diff --git a/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx index f82e47809d08..84ea11021148 100644 --- a/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx +++ b/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx @@ -12,13 +12,19 @@ import BankAccount from '@libs/models/BankAccount'; import EnableBankAccount from '@pages/ReimbursementAccount/EnableBankAccount/EnableBankAccount'; import * as Report from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Account, ReimbursementAccount} from '@src/types/onyx'; +import type {Account, Policy, ReimbursementAccount} from '@src/types/onyx'; import BankAccountValidationForm from './components/BankAccountValidationForm'; import FinishChatCard from './components/FinishChatCard'; type ConnectBankAccountOnyxProps = { /** User's account who is setting up bank account */ account: OnyxEntry; + + /** The policy which the user has access to and which the report is tied to */ + policy: OnyxEntry; + + /** Reimbursement account from ONYX */ + reimbursementAccount: OnyxEntry; }; type ConnectBankAccountProps = ConnectBankAccountOnyxProps & { @@ -29,11 +35,11 @@ type ConnectBankAccountProps = ConnectBankAccountOnyxProps & { onBackButtonPress: () => void; }; -function ConnectBankAccount({reimbursementAccount, onBackButtonPress, account}: ConnectBankAccountProps) { +function ConnectBankAccount({reimbursementAccount, onBackButtonPress, account, policy}: ConnectBankAccountProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const handleNavigateToConciergeChat = () => Report.navigateToConciergeChat(); + const handleNavigateToConciergeChat = () => Report.navigateToConciergeChat(false, true); const bankAccountState = reimbursementAccount.achData?.state ?? ''; // If a user tries to navigate directly to the validate page we'll show them the EnableStep @@ -74,6 +80,7 @@ function ConnectBankAccount({reimbursementAccount, onBackButtonPress, account}: )} {isBankAccountVerifying && ( @@ -92,4 +99,10 @@ export default withOnyx({ account: { key: ONYXKEYS.ACCOUNT, }, + policy: { + key: ({reimbursementAccount}) => `${ONYXKEYS.COLLECTION.POLICY}${reimbursementAccount?.achData?.policyID}`, + }, + reimbursementAccount: { + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + }, })(ConnectBankAccount); diff --git a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx index f2707d23f03d..506e6410440e 100644 --- a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx +++ b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx @@ -7,11 +7,13 @@ import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as CurrencyUtils from '@libs/CurrencyUtils'; +import getPermittedDecimalSeparator from '@libs/getPermittedDecimalSeparator'; import * as ValidationUtils from '@libs/ValidationUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount} from '@src/types/onyx'; +import type {Policy, ReimbursementAccount} from '@src/types/onyx'; import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; import Enable2FACard from './Enable2FACard'; @@ -21,6 +23,9 @@ type BankAccountValidationFormProps = { /** Boolean required to display Enable2FACard component */ requiresTwoFactorAuth: boolean; + + /** The policy which the user has access to and which the report is tied to */ + policy: Policy | null; }; const getAmountValues = (values: ReimbursementAccountDraftValues): Record => ({ @@ -29,41 +34,41 @@ const getAmountValues = (values: ReimbursementAccountDraftValues): Record { - const value = amount ? amount.trim() : ''; - if (value === '' || Number.isNaN(Number(value)) || !Math.abs(Str.fromUSDToNumber(value, true))) { +const filterInput = (amount: string, amountRegex?: RegExp) => { + let value = amount ? amount.toString().trim() : ''; + value = value.replace(/^0+|0+$/g, ''); + if (value === '' || Number.isNaN(Number(value)) || !Math.abs(Str.fromUSDToNumber(value, false)) || (amountRegex && !amountRegex.test(value))) { return ''; } - // If the user enters the values in dollars, convert it to the respective cents amount - if (value.includes('.')) { - return Str.fromUSDToNumber(value, true); - } - return value; }; -const validate = (values: ReimbursementAccountDraftValues) => { - const errors: Record = {}; - const amountValues = getAmountValues(values); +function BankAccountValidationForm({requiresTwoFactorAuth, reimbursementAccount, policy}: BankAccountValidationFormProps) { + const {translate, toLocaleDigit} = useLocalize(); + const styles = useThemeStyles(); - Object.keys(amountValues).forEach((key) => { - const value = amountValues[key]; - const filteredValue = filterInput(value); - if (ValidationUtils.isRequiredFulfilled(filteredValue.toString())) { - return; - } - errors[key] = 'common.error.invalidAmount'; - }); + const policyID = reimbursementAccount?.achData?.policyID ?? ''; - return errors; -}; + const validate = (values: ReimbursementAccountDraftValues) => { + const errors: Record = {}; + const amountValues = getAmountValues(values); + const decimalSeparator = toLocaleDigit('.'); + const outputCurrency = policy?.outputCurrency ?? CONST.CURRENCY.USD; + const amountRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{0,${CurrencyUtils.getCurrencyDecimals(outputCurrency)}})?$`, 'i'); + + Object.keys(amountValues).forEach((key) => { + const value = amountValues[key]; + const filteredValue = filterInput(value, amountRegex); + if (ValidationUtils.isRequiredFulfilled(filteredValue.toString())) { + return; + } + errors[key] = 'common.error.invalidAmount'; + }); -function BankAccountValidationForm({requiresTwoFactorAuth, reimbursementAccount}: BankAccountValidationFormProps) { - const {translate} = useLocalize(); - const styles = useThemeStyles(); + return errors; + }; - const policyID = reimbursementAccount?.achData?.policyID ?? ''; const submit = useCallback( (values: ReimbursementAccountDraftValues) => { const amount1 = filterInput(values.amount1 ?? ''); diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index fc7a631a44e2..cc416a5cfbdd 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -529,13 +529,7 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol } if (currentStep === CONST.BANK_ACCOUNT.STEP.VALIDATION) { - return ( - - ); + return ; } if (currentStep === CONST.BANK_ACCOUNT.STEP.ENABLE) {