From e3c01460ab814c6439aa1c4a414c9abef39b1370 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Fri, 27 Jun 2025 17:41:42 +0200 Subject: [PATCH 1/9] Refactor bank account creation logic and remove sideeffect command --- src/libs/API/types.ts | 1 - src/libs/actions/BankAccounts.ts | 48 +++++++++++++++++-- .../substeps/Confirmation.tsx | 36 ++++++-------- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index e03398586a3c..76ef8a123ada 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -1155,7 +1155,6 @@ const SIDE_EFFECT_REQUEST_COMMANDS = { DISCONNECT_AS_DELEGATE: 'DisconnectAsDelegate', COMPLETE_HYBRID_APP_ONBOARDING: 'CompleteHybridAppOnboarding', CONNECT_POLICY_TO_QUICKBOOKS_DESKTOP: 'ConnectPolicyToQuickbooksDesktop', - BANK_ACCOUNT_CREATE_CORPAY: 'BankAccount_CreateCorpay', MERGE_INTO_ACCOUNT_AND_LOGIN: 'MergeIntoAccountAndLogIn', // PayMoneyRequestOnSearch only works online (pattern C) and we need to play the success sound only when the request is successful diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 5bd7d61393e0..4353a14e96bf 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -15,7 +15,7 @@ import type { } from '@libs/API/parameters'; import type {SaveCorpayOnboardingCompanyDetails} from '@libs/API/parameters/SaveCorpayOnboardingCompanyDetailsParams'; import type SaveCorpayOnboardingDirectorInformationParams from '@libs/API/parameters/SaveCorpayOnboardingDirectorInformationParams'; -import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import {getMicroSecondOnyxErrorWithTranslationKey} from '@libs/ErrorUtils'; import {getLastUsedPaymentMethod} from '@libs/IOUUtils'; import {translateLocal} from '@libs/Localize'; @@ -987,8 +987,50 @@ function createCorpayBankAccountForWalletFlow(data: InternationalBankAccountForm country: data.bankCountry, currency: data.bankCurrency, }; - // eslint-disable-next-line rulesdir/no-api-side-effects-method - return API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.BANK_ACCOUNT_CREATE_CORPAY, {isWithdrawal: false, isSavings: true, inputs: JSON.stringify(inputData)}); + + const parameters = { + isWithdrawal: false, + isSavings: true, + inputs: JSON.stringify(inputData), + }; + + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + value: { + isLoading: true, + isCreateCorpayBankAccount: true, + }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + value: { + isLoading: false, + isCreateCorpayBankAccount: false, + errors: null, + isSuccess: true, + }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + value: { + isLoading: false, + isCreateCorpayBankAccount: false, + isSuccess: false, + }, + }, + ], + }; + + return API.write(WRITE_COMMANDS.BANK_ACCOUNT_CREATE_CORPAY, parameters, onyxData); } export { diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index f794c46b69fc..b5badadde975 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -1,10 +1,9 @@ -import React, {useCallback, useState} from 'react'; +import React, {useCallback, useEffect} from 'react'; import {useOnyx} from 'react-native-onyx'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; -import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; @@ -44,9 +43,8 @@ function TermsAndConditionsLabel() { function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [isSubmitting, setIsSubmitting] = useState(false); - const [error, setError] = useState(''); const [corpayFields] = useOnyx(ONYXKEYS.CORPAY_FIELDS, {canBeMissing: false}); + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); const {isOffline} = useNetwork(); const getTitle = (field: CorpayFormField, fieldName: string) => { @@ -62,25 +60,24 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp }; const getDataAndGoToNextStep = (values: FormOnyxValues) => { - setError(''); - setIsSubmitting(true); createCorpayBankAccountForWalletFlow( {...formValues, ...values}, corpayFields?.classification ?? '', corpayFields?.destinationCountry ?? '', corpayFields?.preferredMethod ?? '', - ).then((response) => { - setIsSubmitting(false); - if (response?.jsonCode) { - if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { - onNext(); - } else { - setError(response.message ?? ''); - } - } - }); + ); }; + useEffect(() => { + if (reimbursementAccount?.isLoading === true || !!reimbursementAccount?.errors) { + return; + } + + if (reimbursementAccount?.isSuccess === true) { + onNext(); + } + }, [reimbursementAccount?.isLoading, reimbursementAccount?.isSuccess, reimbursementAccount?.errors, onNext]); + const summaryItems: MenuItemProps[] = [ { description: translate('common.country'), @@ -185,7 +182,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp submitButtonText={translate('common.confirm')} style={[styles.mh5, styles.flexGrow1]} enabledWhenOffline={false} - isLoading={isSubmitting} + isLoading={reimbursementAccount?.isLoading} shouldHideFixErrorsAlert > - ); From 733335739ca18ff3df82de9cb5dc22beab925011 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 30 Jun 2025 13:59:03 +0200 Subject: [PATCH 2/9] fix: remove unused bank account create command and ensure reimbursement account is always available --- src/libs/API/types.ts | 1 - .../InternationalDepositAccount/substeps/Confirmation.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index fabba330adac..62698b72f8f1 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -1181,7 +1181,6 @@ type SideEffectRequestCommandParameters = { [SIDE_EFFECT_REQUEST_COMMANDS.DISCONNECT_AS_DELEGATE]: EmptyObject; [SIDE_EFFECT_REQUEST_COMMANDS.COMPLETE_HYBRID_APP_ONBOARDING]: EmptyObject; [SIDE_EFFECT_REQUEST_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_DESKTOP]: Parameters.ConnectPolicyToQuickBooksDesktopParams; - [SIDE_EFFECT_REQUEST_COMMANDS.BANK_ACCOUNT_CREATE_CORPAY]: Parameters.BankAccountCreateCorpayParams; [SIDE_EFFECT_REQUEST_COMMANDS.PAY_MONEY_REQUEST_ON_SEARCH]: Parameters.PayMoneyRequestOnSearchParams; [SIDE_EFFECT_REQUEST_COMMANDS.MERGE_INTO_ACCOUNT_AND_LOGIN]: Parameters.MergeIntoAccountAndLogInParams; [SIDE_EFFECT_REQUEST_COMMANDS.LOG_OUT]: Parameters.LogOutParams; diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index b5badadde975..02b59921b69b 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -44,7 +44,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp const {translate} = useLocalize(); const styles = useThemeStyles(); const [corpayFields] = useOnyx(ONYXKEYS.CORPAY_FIELDS, {canBeMissing: false}); - const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false}); const {isOffline} = useNetwork(); const getTitle = (field: CorpayFormField, fieldName: string) => { From 3cbbad09e96c327e8529f130f6f55f96ac56204c Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 30 Jun 2025 14:00:53 +0200 Subject: [PATCH 3/9] fix: prettier --- src/libs/actions/BankAccounts.ts | 4 ++-- .../InternationalDepositAccount/substeps/Confirmation.tsx | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 4353a14e96bf..ba5717ae1b81 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -987,9 +987,9 @@ function createCorpayBankAccountForWalletFlow(data: InternationalBankAccountForm country: data.bankCountry, currency: data.bankCurrency, }; - + const parameters = { - isWithdrawal: false, + isWithdrawal: false, isSavings: true, inputs: JSON.stringify(inputData), }; diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index 02b59921b69b..2594bf32b25f 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -60,12 +60,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp }; const getDataAndGoToNextStep = (values: FormOnyxValues) => { - createCorpayBankAccountForWalletFlow( - {...formValues, ...values}, - corpayFields?.classification ?? '', - corpayFields?.destinationCountry ?? '', - corpayFields?.preferredMethod ?? '', - ); + createCorpayBankAccountForWalletFlow({...formValues, ...values}, corpayFields?.classification ?? '', corpayFields?.destinationCountry ?? '', corpayFields?.preferredMethod ?? ''); }; useEffect(() => { From 9533d39c8f43dc78631ba00f8767f985c4cf0c49 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 30 Jun 2025 14:57:10 +0200 Subject: [PATCH 4/9] fix: clear reimbursement account bank creation after successful confirmation --- .../InternationalDepositAccount/substeps/Confirmation.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index 2594bf32b25f..a50ff8623d9d 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -13,7 +13,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import {getCurrencySymbol} from '@libs/CurrencyUtils'; import type CustomSubStepProps from '@pages/settings/Wallet/InternationalDepositAccount/types'; -import {createCorpayBankAccountForWalletFlow} from '@userActions/BankAccounts'; +import {clearReimbursementAccountBankCreation, createCorpayBankAccountForWalletFlow} from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -70,6 +70,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp if (reimbursementAccount?.isSuccess === true) { onNext(); + clearReimbursementAccountBankCreation(); } }, [reimbursementAccount?.isLoading, reimbursementAccount?.isSuccess, reimbursementAccount?.errors, onNext]); From fddfd9f18352244cb64e1193df7fcedaa74bdba6 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 7 Jul 2025 17:25:25 +0200 Subject: [PATCH 5/9] fix conflict --- .../Wallet/InternationalDepositAccount/substeps/Confirmation.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index aeefac524c26..5390e443a4b5 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -1,5 +1,4 @@ import React, {useCallback, useEffect} from 'react'; -import {useOnyx} from 'react-native-onyx'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; From 99ae8ce7f5c5fbc9d04f3cca848756825abedb26 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 22 Jul 2025 14:38:49 +0200 Subject: [PATCH 6/9] Add error handling to Confirmation step in International Deposit Account --- .../substeps/Confirmation.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index 5390e443a4b5..b64a95b7b697 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -2,7 +2,8 @@ import React, {useCallback, useEffect} from 'react'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types' +import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; @@ -12,6 +13,7 @@ import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; import {getCurrencySymbol} from '@libs/CurrencyUtils'; +import * as ErrorUtils from '@libs/ErrorUtils'; import type CustomSubStepProps from '@pages/settings/Wallet/InternationalDepositAccount/types'; import {clearReimbursementAccountBankCreation, createCorpayBankAccountForWalletFlow} from '@userActions/BankAccounts'; import CONST from '@src/CONST'; @@ -155,6 +157,8 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp [translate], ); + const errorMessage = ErrorUtils.getLatestErrorMessage(reimbursementAccount); + return ( {translate('addPersonalBankAccount.confirmationStepHeader')} @@ -189,6 +193,13 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp style={[styles.mt3]} shouldSaveDraft /> + {!!errorMessage && ( + + )} ); From 4e25ccbb9b9711b29844d1d0ddbb58cbd645cf85 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 22 Jul 2025 15:36:24 +0200 Subject: [PATCH 7/9] fix prettier --- .../InternationalDepositAccount/substeps/Confirmation.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index b64a95b7b697..f55d09927656 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -2,7 +2,7 @@ import React, {useCallback, useEffect} from 'react'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {FormInputErrors, FormOnyxValues} from '@components/Form/types' +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScrollView from '@components/ScrollView'; @@ -158,7 +158,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp ); const errorMessage = ErrorUtils.getLatestErrorMessage(reimbursementAccount); - + return ( {translate('addPersonalBankAccount.confirmationStepHeader')} @@ -194,7 +194,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp shouldSaveDraft /> {!!errorMessage && ( - Date: Tue, 22 Jul 2025 17:42:54 +0200 Subject: [PATCH 8/9] fix lint --- .../InternationalDepositAccount/substeps/Confirmation.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index f55d09927656..cc16a96be992 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -13,7 +13,7 @@ import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; import {getCurrencySymbol} from '@libs/CurrencyUtils'; -import * as ErrorUtils from '@libs/ErrorUtils'; +import {getLatestErrorMessage} from '@libs/ErrorUtils'; import type CustomSubStepProps from '@pages/settings/Wallet/InternationalDepositAccount/types'; import {clearReimbursementAccountBankCreation, createCorpayBankAccountForWalletFlow} from '@userActions/BankAccounts'; import CONST from '@src/CONST'; @@ -157,7 +157,7 @@ function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProp [translate], ); - const errorMessage = ErrorUtils.getLatestErrorMessage(reimbursementAccount); + const errorMessage = getLatestErrorMessage(reimbursementAccount); return ( From f8e834dc7005b52f9b672ee748ab1771f10cb61a Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 23 Jul 2025 19:05:02 +0200 Subject: [PATCH 9/9] fix: add generic bank error --- src/libs/actions/BankAccounts.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index c478c584c17e..d0065afc5f5a 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -954,6 +954,7 @@ function createCorpayBankAccountForWalletFlow(data: InternationalBankAccountForm isLoading: false, isCreateCorpayBankAccount: false, isSuccess: false, + errors: getMicroSecondOnyxErrorWithTranslationKey('walletPage.addBankAccountFailure'), }, }, ],