From 9fa68782c438c22d5cd725a826bc4a748b515a3e Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 31 Jul 2025 17:56:15 +0530 Subject: [PATCH 01/12] refactor store.ts to remove usage of Onyx.connect --- src/libs/ReportUtils.ts | 10 ++++++++-- src/libs/actions/ReimbursementAccount/store.ts | 12 +----------- src/pages/home/report/ReportActionItem.tsx | 4 ++-- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index d9981d9d2666..fdeb008de577 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -28,6 +28,7 @@ import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import type { + BankAccountList, Beta, IntroSelected, NewGroupChatDraft, @@ -9667,7 +9668,12 @@ function isAllowedToSubmitDraftExpenseReport(report: OnyxEntry): boolean /** * What missing payment method does this report action indicate, if any? */ -function getIndicatedMissingPaymentMethod(userWallet: OnyxEntry, reportId: string | undefined, reportAction: ReportAction): MissingPaymentMethod | undefined { +function getIndicatedMissingPaymentMethod( + userWallet: OnyxEntry, + reportId: string | undefined, + reportAction: ReportAction, + bankAccountList: OnyxEntry, +): MissingPaymentMethod | undefined { const isSubmitterOfUnsettledReport = reportId && isCurrentUserSubmitter(getReport(reportId, allReports)) && !isSettled(reportId); if (!reportId || !isSubmitterOfUnsettledReport || !isReimbursementQueuedAction(reportAction)) { return undefined; @@ -9677,7 +9683,7 @@ function getIndicatedMissingPaymentMethod(userWallet: OnyxEntry, rep return isEmpty(userWallet) || userWallet.tierName === CONST.WALLET.TIER_NAME.SILVER ? 'wallet' : undefined; } - return !hasCreditBankAccount() ? 'bankAccount' : undefined; + return !hasCreditBankAccount(bankAccountList) ? 'bankAccount' : undefined; } /** diff --git a/src/libs/actions/ReimbursementAccount/store.ts b/src/libs/actions/ReimbursementAccount/store.ts index bc298313ad1e..a92778fc50a3 100644 --- a/src/libs/actions/ReimbursementAccount/store.ts +++ b/src/libs/actions/ReimbursementAccount/store.ts @@ -1,18 +1,8 @@ import type {OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; import BankAccount from '@libs/models/BankAccount'; -import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; -let bankAccountList: OnyxEntry; -Onyx.connect({ - key: ONYXKEYS.BANK_ACCOUNT_LIST, - callback: (val) => { - bankAccountList = val; - }, -}); - -function hasCreditBankAccount(): boolean { +function hasCreditBankAccount(bankAccountList: OnyxEntry): boolean { if (!bankAccountList) { return false; } diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index aadfc5340973..d34318329d85 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -72,7 +72,7 @@ function ReportActionItem({allReports, policies, action, report, transactions, s canBeMissing: true, selector: (transaction) => transaction?.errorFields?.route ?? null, }); - + const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST, {canBeMissing: true}); const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true}); // The app would crash due to subscribing to the entire report collection if parentReportID is an empty string. So we should have a fallback ID here. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -81,7 +81,7 @@ function ReportActionItem({allReports, policies, action, report, transactions, s const blockedFromConcierge = useBlockedFromConcierge(); const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true}); const targetReport = isChatThread(report) ? parentReport : report; - const missingPaymentMethod = getIndicatedMissingPaymentMethod(userWallet, targetReport?.reportID, action); + const missingPaymentMethod = getIndicatedMissingPaymentMethod(userWallet, targetReport?.reportID, action, bankAccountList); const taskReport = originalMessage && 'taskReportID' in originalMessage ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${originalMessage.taskReportID}`] : undefined; const linkedReport = originalMessage && 'linkedReportID' in originalMessage ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${originalMessage.linkedReportID}`] : undefined; From 6bcc300df7247d9fe1a72790e0e0de17fda90e03 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 31 Jul 2025 18:05:37 +0530 Subject: [PATCH 02/12] fix typefailure --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index fdeb008de577..6d86e7a5d80d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -9689,11 +9689,11 @@ function getIndicatedMissingPaymentMethod( /** * Checks if report chat contains missing payment method */ -function hasMissingPaymentMethod(userWallet: OnyxEntry, iouReportID: string | undefined): boolean { +function hasMissingPaymentMethod(userWallet: OnyxEntry, iouReportID: string | undefined, bankAccountList: OnyxEntry): boolean { const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`] ?? {}; return Object.values(reportActions) .filter(Boolean) - .some((action) => getIndicatedMissingPaymentMethod(userWallet, iouReportID, action) !== undefined); + .some((action) => getIndicatedMissingPaymentMethod(userWallet, iouReportID, action, bankAccountList) !== undefined); } /** From bbc0684416a5a0219d99802369aec766f70c24cf Mon Sep 17 00:00:00 2001 From: allgandalf Date: Wed, 20 Aug 2025 16:55:04 +0530 Subject: [PATCH 03/12] fix lint --- src/libs/ReportUtils.ts | 2 +- src/pages/home/report/ReportActionItem.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 6f8c9fe23635..1aa8f482c676 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -9861,7 +9861,7 @@ function hasMissingPaymentMethod(userWalletTierName: string | undefined, iouRepo const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`] ?? {}; return Object.values(reportActions) .filter(Boolean) - .some((action) => getIndicatedMissingPaymentMethod(userWallet, iouReportID, action, bankAccountList) !== undefined); + .some((action) => getIndicatedMissingPaymentMethod(userWalletTierName, iouReportID, action, bankAccountList) !== undefined); } /** diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index f76b0f3e0193..3a66455dcfc9 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -1,5 +1,6 @@ import React, {useMemo} from 'react'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import useOnyx from '@hooks/useOnyx'; import {useBlockedFromConcierge} from '@components/OnyxListItemProvider'; import useReportIsArchived from '@hooks/useReportIsArchived'; import ModifiedExpenseMessage from '@libs/ModifiedExpenseMessage'; @@ -96,7 +97,7 @@ function ReportActionItem({ const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID || undefined}`]; const blockedFromConcierge = useBlockedFromConcierge(); const targetReport = isChatThread(report) ? parentReport : report; - const missingPaymentMethod = getIndicatedMissingPaymentMethod(userWalletTierName, targetReport?.reportID, action); + const missingPaymentMethod = getIndicatedMissingPaymentMethod(userWalletTierName, targetReport?.reportID, action, bankAccountList); const taskReport = originalMessage && 'taskReportID' in originalMessage ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${originalMessage.taskReportID}`] : undefined; const linkedReport = originalMessage && 'linkedReportID' in originalMessage ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${originalMessage.linkedReportID}`] : undefined; From 377122e565da4ca9e514ed99a22ac466f65e9a27 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Wed, 20 Aug 2025 16:55:27 +0530 Subject: [PATCH 04/12] fix prettier --- src/pages/home/report/ReportActionItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index 3a66455dcfc9..27730fadf7a8 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -1,7 +1,7 @@ import React, {useMemo} from 'react'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import useOnyx from '@hooks/useOnyx'; import {useBlockedFromConcierge} from '@components/OnyxListItemProvider'; +import useOnyx from '@hooks/useOnyx'; import useReportIsArchived from '@hooks/useReportIsArchived'; import ModifiedExpenseMessage from '@libs/ModifiedExpenseMessage'; import {getIOUReportIDFromReportActionPreview, getOriginalMessage} from '@libs/ReportActionsUtils'; From 28f04225acc09e0dc1a12a7909b1deca4ffe27d3 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 21 Aug 2025 19:34:59 +0530 Subject: [PATCH 05/12] update max warning --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 350b8ab00106..6362194a2162 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand", "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure", "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc", - "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=246 --cache --cache-location=node_modules/.cache/eslint", + "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=245 --cache --cache-location=node_modules/.cache/eslint", "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh", "lint-watch": "npx eslint-watch --watch --changed", "shellcheck": "./scripts/shellCheck.sh", From f785d6230f7c2a7a93360c1ab874206e08459137 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 21 Aug 2025 22:43:17 +0530 Subject: [PATCH 06/12] add unit test for hasCreditBankAccount --- src/CONST/index.ts | 14 +++++++++-- src/libs/models/BankAccount.ts | 21 +++++----------- tests/unit/ReimbursementAccountTest.ts | 33 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 tests/unit/ReimbursementAccountTest.ts diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 492bab63236d..78dfa1f95a16 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -7,7 +7,6 @@ import type {ValueOf} from 'type-fest'; import type {SearchFilterKey} from '@components/Search/types'; import type ResponsiveLayoutResult from '@hooks/useResponsiveLayout/types'; import type {MileageRate} from '@libs/DistanceRequestUtils'; -import BankAccount from '@libs/models/BankAccount'; import {addTrailingForwardSlash} from '@libs/Url'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -57,6 +56,8 @@ const keyInputSpace = ' '; // describes if a shortcut key can cause navigation const KEYBOARD_SHORTCUT_NAVIGATION_TYPE = 'NAVIGATION_SHORTCUT'; +const SETUP_STATE = 'SETUP'; + const chatTypes = { POLICY_ANNOUNCE: 'policyAnnounce', POLICY_ADMINS: 'policyAdmins', @@ -5502,12 +5503,21 @@ const CONST = { }, }, + BANK_ACCOUNT_STATE: { + PENDING: 'PENDING', + OPEN: 'OPEN', + DELETED: 'DELETED', + LOCKED: 'LOCKED', + SETUP: SETUP_STATE, + VERIFYING: 'VERIFYING', + }, + // We need to store this server side error in order to not show the blocking screen when the error is for invalid code MERGE_ACCOUNT_INVALID_CODE_ERROR: '401 Not authorized - Invalid validateCode', REIMBURSEMENT_ACCOUNT: { DEFAULT_DATA: { achData: { - state: BankAccount.STATE.SETUP, + state: SETUP_STATE, }, isLoading: false, errorFields: {}, diff --git a/src/libs/models/BankAccount.ts b/src/libs/models/BankAccount.ts index a86a30b57e86..d6c377958d26 100644 --- a/src/libs/models/BankAccount.ts +++ b/src/libs/models/BankAccount.ts @@ -4,7 +4,7 @@ import CONST from '@src/CONST'; import type {BankAccountAdditionalData} from '@src/types/onyx/BankAccount'; import type BankAccountJSON from '@src/types/onyx/BankAccount'; -type State = ValueOf; +type State = ValueOf; type ACHData = { routingNumber: string; @@ -20,15 +20,6 @@ type ACHData = { class BankAccount { json: BankAccountJSON; - static STATE = { - PENDING: 'PENDING', - OPEN: 'OPEN', - DELETED: 'DELETED', - LOCKED: 'LOCKED', - SETUP: 'SETUP', - VERIFYING: 'VERIFYING', - }; - constructor(accountJSON: BankAccountJSON) { this.json = accountJSON; } @@ -75,7 +66,7 @@ class BankAccount { } isOpen() { - return this.getState() === BankAccount.STATE.OPEN; + return this.getState() === CONST.BANK_ACCOUNT_STATE.OPEN; } /** @@ -89,25 +80,25 @@ class BankAccount { * If the user still needs to enter the 3 micro deposit amounts. */ isPending() { - return this.getState() === BankAccount.STATE.PENDING; + return this.getState() === CONST.BANK_ACCOUNT_STATE.PENDING; } /** * If success team is currently verifying the bank account data provided by the user. */ isVerifying() { - return this.getState() === BankAccount.STATE.VERIFYING; + return this.getState() === CONST.BANK_ACCOUNT_STATE.VERIFYING; } /** * If the user didn't finish entering all their info. */ isInSetup() { - return this.getState() === BankAccount.STATE.SETUP; + return this.getState() === CONST.BANK_ACCOUNT_STATE.SETUP; } isLocked() { - return this.getState() === BankAccount.STATE.LOCKED; + return this.getState() === CONST.BANK_ACCOUNT_STATE.LOCKED; } /** diff --git a/tests/unit/ReimbursementAccountTest.ts b/tests/unit/ReimbursementAccountTest.ts new file mode 100644 index 000000000000..cf9babd2af29 --- /dev/null +++ b/tests/unit/ReimbursementAccountTest.ts @@ -0,0 +1,33 @@ +import {hasCreditBankAccount} from '@src/libs/actions/ReimbursementAccount/store'; +import type {BankAccountList} from '@src/types/onyx'; + +describe('ReimbursementAccountTest', () => { + describe('hasCreditBankAccount', () => { + it('should return true if there is a credit bank account', () => { + const BANK_ACCOUNT_LIST: BankAccountList = { + // eslint-disable-next-line @typescript-eslint/naming-convention + '1': {accountData: {defaultCredit: true}, bankCurrency: 'USD', bankCountry: 'US'}, + // eslint-disable-next-line @typescript-eslint/naming-convention + '2': {accountData: {defaultCredit: false}, bankCurrency: 'USD', bankCountry: 'US'}, + }; + + const result = hasCreditBankAccount(BANK_ACCOUNT_LIST); + expect(result).toBe(true); + }); + + it('should return false if there is no credit bank account', () => { + const BANK_ACCOUNT_LIST: BankAccountList = { + // eslint-disable-next-line @typescript-eslint/naming-convention + '1': {accountData: {defaultCredit: false}, bankCurrency: 'USD', bankCountry: 'US'}, + }; + + const result = hasCreditBankAccount(BANK_ACCOUNT_LIST); + expect(result).toBe(false); + }); + + it('should return false if there is no bank account list', () => { + const result = hasCreditBankAccount(undefined); + expect(result).toBe(false); + }); + }); +}); From 1a587dde35f0430a5ac1b0279876b82beff8a9ba Mon Sep 17 00:00:00 2001 From: Gandalf Date: Thu, 21 Aug 2025 22:46:05 +0530 Subject: [PATCH 07/12] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74f8dce17bd6..801341ed68bb 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand", "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure", "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc", - "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=245 --cache --cache-location=node_modules/.cache/eslint", + "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=244 --cache --cache-location=node_modules/.cache/eslint", "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh", "lint-watch": "npx eslint-watch --watch --changed", "shellcheck": "./scripts/shellCheck.sh", From d439e49f1cccf36d34bc6a5fdad98cba82051bcb Mon Sep 17 00:00:00 2001 From: Gandalf Date: Fri, 22 Aug 2025 10:04:47 +0530 Subject: [PATCH 08/12] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 801341ed68bb..68695cac4b7d 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand", "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure", "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc", - "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=244 --cache --cache-location=node_modules/.cache/eslint", + "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=243 --cache --cache-location=node_modules/.cache/eslint", "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh", "lint-watch": "npx eslint-watch --watch --changed", "shellcheck": "./scripts/shellCheck.sh", From 950b3d434e89723262b90733bc14060752f5d843 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 4 Sep 2025 00:46:25 +0530 Subject: [PATCH 09/12] fix typescript failure --- .../ReimbursementAccount/ReimbursementAccountPage.tsx | 7 +++---- .../USD/BusinessInfo/BusinessInfo.tsx | 3 +-- .../USD/BusinessInfo/subSteps/NameBusiness.tsx | 4 ++-- .../USD/BusinessInfo/subSteps/TaxIdBusiness.tsx | 3 +-- .../USD/ConnectBankAccount/ConnectBankAccount.tsx | 8 ++++---- .../USD/Requestor/PersonalInfo/PersonalInfo.tsx | 3 +-- src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx | 3 +-- src/pages/workspace/WorkspacePageWithSections.tsx | 3 +-- src/pages/workspace/WorkspaceResetBankAccountModal.tsx | 4 ++-- 9 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx index ca846c553257..28dd46a5a062 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx @@ -21,7 +21,6 @@ import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; import {isCurrencySupportedForECards} from '@libs/CardUtils'; -import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {ReimbursementAccountNavigatorParamList} from '@libs/Navigation/types'; @@ -131,7 +130,7 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}: * Returns true if a VBBA exists in any state other than OPEN or LOCKED */ const hasInProgressVBBA = useCallback((): boolean => { - return !!achData?.bankAccountID && !!achData?.state && achData?.state !== BankAccount.STATE.OPEN && achData?.state !== BankAccount.STATE.LOCKED; + return !!achData?.bankAccountID && !!achData?.state && achData?.state !== CONST.BANK_ACCOUNT_STATE.OPEN && achData?.state !== CONST.BANK_ACCOUNT_STATE.LOCKED; }, [achData?.bankAccountID, achData?.state]); /** Returns true if user passed first step of flow for non USD VBBA */ @@ -357,9 +356,9 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}: break; case CONST.BANK_ACCOUNT.STEP.VALIDATION: - if ([BankAccount.STATE.VERIFYING, BankAccount.STATE.SETUP].some((value) => value === achData?.state)) { + if ([CONST.BANK_ACCOUNT_STATE.VERIFYING, CONST.BANK_ACCOUNT_STATE.SETUP].some((value) => value === achData?.state)) { goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT); - } else if (!isOffline && achData?.state === BankAccount.STATE.PENDING) { + } else if (!isOffline && achData?.state === CONST.BANK_ACCOUNT_STATE.PENDING) { setShouldShowContinueSetupButton(true); setUSDBankAccountStep(null); } else { diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx index 27f9d09d0b2e..7aa07661da15 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx @@ -6,7 +6,6 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useSubStep from '@hooks/useSubStep'; import type {SubStepProps} from '@hooks/useSubStep/types'; -import BankAccount from '@libs/models/BankAccount'; import {parsePhoneNumber} from '@libs/PhoneNumber'; import {isValidWebsite} from '@libs/ValidationUtils'; import getInitialSubStepForBusinessInfo from '@pages/ReimbursementAccount/USD/utils/getInitialSubStepForBusinessInfo'; @@ -81,7 +80,7 @@ function BusinessInfo({onBackButtonPress}: BusinessInfoProps) { [reimbursementAccount, values, getBankAccountFields, policyID], ); - const isBankAccountVerifying = reimbursementAccount?.achData?.state === BankAccount.STATE.VERIFYING; + const isBankAccountVerifying = reimbursementAccount?.achData?.state === CONST.BANK_ACCOUNT_STATE.VERIFYING; const startFrom = useMemo(() => (isBankAccountVerifying ? 0 : getInitialSubStepForBusinessInfo(values)), [values, isBankAccountVerifying]); const { diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx index e6dc95270ff9..8be967ed720b 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx @@ -5,7 +5,7 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; import type {SubStepProps} from '@hooks/useSubStep/types'; -import BankAccount from '@libs/models/BankAccount'; +import CONST from '@src/CONST'; import {getFieldRequiredErrors, isValidCompanyName} from '@libs/ValidationUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; @@ -22,7 +22,7 @@ function NameBusiness({onNext, onMove, isEditing}: SubStepProps) { const bankAccountID = reimbursementAccount?.achData?.bankAccountID; const bankAccountState = reimbursementAccount?.achData?.state ?? ''; - const shouldDisableCompanyName = !!(bankAccountID && defaultCompanyName && ![BankAccount.STATE.SETUP, BankAccount.STATE.VERIFYING].includes(bankAccountState)); + const shouldDisableCompanyName = !!(bankAccountID && defaultCompanyName && ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP)); const validate = useCallback( (values: FormOnyxValues): FormInputErrors => { diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx index 3760c42a82a6..c15de6efe2de 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx @@ -6,7 +6,6 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; import type {SubStepProps} from '@hooks/useSubStep/types'; -import BankAccount from '@libs/models/BankAccount'; import {getFieldRequiredErrors, isValidTaxID} from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -26,7 +25,7 @@ function TaxIdBusiness({onNext, onMove, isEditing}: SubStepProps) { const defaultCompanyTaxID = reimbursementAccount?.achData?.companyTaxID ?? ''; const bankAccountID = reimbursementAccount?.achData?.bankAccountID; const bankAccountState = reimbursementAccount?.achData?.state ?? ''; - const shouldDisableCompanyTaxID = !!(bankAccountID && defaultCompanyTaxID && ![BankAccount.STATE.SETUP, BankAccount.STATE.VERIFYING].includes(bankAccountState)); + const shouldDisableCompanyTaxID = !!(bankAccountID && defaultCompanyTaxID && ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP)); const validate = useCallback( (values: FormOnyxValues): FormInputErrors => { diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx index 5ebb61d95894..c7952f7a317d 100644 --- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx +++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx @@ -7,7 +7,7 @@ import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; -import BankAccount from '@libs/models/BankAccount'; +import CONST from '@src/CONST'; import ConnectedVerifiedBankAccount from '@pages/ReimbursementAccount/ConnectedVerifiedBankAccount'; import {navigateToConciergeChat} from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -37,7 +37,7 @@ function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBa const bankAccountState = reimbursementAccount?.achData?.state ?? ''; // If a user tries to navigate directly to the validate page we'll show them the EnableStep - if (bankAccountState === BankAccount.STATE.OPEN) { + if (bankAccountState === CONST.BANK_ACCOUNT_STATE.OPEN) { return ( (isBankAccountVerifying ? 0 : getInitialSubStepForPersonalInfo(values)), [values, isBankAccountVerifying]); const { diff --git a/src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx b/src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx index 97bc32160ee4..1d3da6aae739 100644 --- a/src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx @@ -8,7 +8,6 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; import mapCurrencyToCountry from '@libs/mapCurrencyToCountry'; -import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import {goBackFromInvalidPolicy} from '@libs/PolicyUtils'; import {clearCorpayBankAccountFields} from '@userActions/BankAccounts'; @@ -33,7 +32,7 @@ function WorkspaceOverviewCurrencyPage({policy}: WorkspaceOverviewCurrencyPagePr const {translate} = useLocalize(); const {isBetaEnabled} = usePermissions(); const [isForcedToChangeCurrency] = useOnyx(ONYXKEYS.IS_FORCED_TO_CHANGE_CURRENCY, {canBeMissing: true}); - const [hasVBA = false] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {selector: (value) => value?.achData?.state === BankAccount.STATE.OPEN, canBeMissing: true}); + const [hasVBA = false] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {selector: (value) => value?.achData?.state === CONST.BANK_ACCOUNT_STATE.OPEN, canBeMissing: true}); const onSelectCurrency = (item: CurrencyListItem) => { if (!policy) { return; diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 78cb678f155b..8f682db87884 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -16,7 +16,6 @@ import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import {openWorkspaceView} from '@libs/actions/BankAccounts'; -import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import {goBackFromInvalidPolicy, isPendingDeletePolicy, isPolicyAdmin, shouldShowPolicy as shouldShowPolicyUtil} from '@libs/PolicyUtils'; import CONST from '@src/CONST'; @@ -140,7 +139,7 @@ function WorkspacePageWithSections({ const isLoading = (reimbursementAccount?.isLoading || isPageLoading) ?? true; const achState = policy?.achAccount?.state ?? reimbursementAccount?.achData?.state; const isUsingECard = account?.isUsingExpensifyCard ?? false; - const hasVBA = achState === BankAccount.STATE.OPEN; + const hasVBA = achState === CONST.BANK_ACCOUNT_STATE.OPEN; const content = typeof children === 'function' ? children(hasVBA, policyID, isUsingECard) : children; const {shouldUseNarrowLayout} = useResponsiveLayout(); const firstRender = useRef(showLoadingAsFirstRender); diff --git a/src/pages/workspace/WorkspaceResetBankAccountModal.tsx b/src/pages/workspace/WorkspaceResetBankAccountModal.tsx index b8f9c80d9064..4e57c015fc20 100644 --- a/src/pages/workspace/WorkspaceResetBankAccountModal.tsx +++ b/src/pages/workspace/WorkspaceResetBankAccountModal.tsx @@ -5,7 +5,7 @@ import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; -import BankAccount from '@libs/models/BankAccount'; +import CONST from '@src/CONST'; import {cancelResetBankAccount, resetNonUSDBankAccount, resetUSDBankAccount} from '@userActions/BankAccounts'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; @@ -44,7 +44,7 @@ function WorkspaceResetBankAccountModal({ const policyID = reimbursementAccount?.achData?.policyID; const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {canBeMissing: true}); const achData = reimbursementAccount?.achData; - const isInOpenState = achData?.state === BankAccount.STATE.OPEN; + const isInOpenState = achData?.state === CONST.BANK_ACCOUNT_STATE.OPEN; const bankAccountID = achData?.bankAccountID; const bankShortName = `${achData?.addressName ?? ''} ${(achData?.accountNumber ?? '').slice(-4)}`; From ca3e409bd6b09b501d222bcb37dc3c873a8a5a48 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 4 Sep 2025 00:47:21 +0530 Subject: [PATCH 10/12] fix: replace BankAccount with CONST --- .../USD/BusinessInfo/subSteps/NameBusiness.tsx | 8 ++++++-- .../USD/BusinessInfo/subSteps/TaxIdBusiness.tsx | 6 +++++- .../USD/ConnectBankAccount/ConnectBankAccount.tsx | 2 +- src/pages/workspace/WorkspaceResetBankAccountModal.tsx | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx index 8be967ed720b..ee150131087a 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx @@ -5,8 +5,8 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; import type {SubStepProps} from '@hooks/useSubStep/types'; -import CONST from '@src/CONST'; import {getFieldRequiredErrors, isValidCompanyName} from '@libs/ValidationUtils'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; @@ -22,7 +22,11 @@ function NameBusiness({onNext, onMove, isEditing}: SubStepProps) { const bankAccountID = reimbursementAccount?.achData?.bankAccountID; const bankAccountState = reimbursementAccount?.achData?.state ?? ''; - const shouldDisableCompanyName = !!(bankAccountID && defaultCompanyName && ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP)); + const shouldDisableCompanyName = !!( + bankAccountID && + defaultCompanyName && + ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP) + ); const validate = useCallback( (values: FormOnyxValues): FormInputErrors => { diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx index c15de6efe2de..ade159288c98 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx @@ -25,7 +25,11 @@ function TaxIdBusiness({onNext, onMove, isEditing}: SubStepProps) { const defaultCompanyTaxID = reimbursementAccount?.achData?.companyTaxID ?? ''; const bankAccountID = reimbursementAccount?.achData?.bankAccountID; const bankAccountState = reimbursementAccount?.achData?.state ?? ''; - const shouldDisableCompanyTaxID = !!(bankAccountID && defaultCompanyTaxID && ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP)); + const shouldDisableCompanyTaxID = !!( + bankAccountID && + defaultCompanyTaxID && + ![CONST.BANK_ACCOUNT_STATE.SETUP, CONST.BANK_ACCOUNT_STATE.VERIFYING].includes(bankAccountState as typeof CONST.BANK_ACCOUNT_STATE.SETUP) + ); const validate = useCallback( (values: FormOnyxValues): FormInputErrors => { diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx index c7952f7a317d..5f8c834d2a06 100644 --- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx +++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx @@ -7,9 +7,9 @@ import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; -import CONST from '@src/CONST'; import ConnectedVerifiedBankAccount from '@pages/ReimbursementAccount/ConnectedVerifiedBankAccount'; import {navigateToConciergeChat} from '@userActions/Report'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import BankAccountValidationForm from './components/BankAccountValidationForm'; import FinishChatCard from './components/FinishChatCard'; diff --git a/src/pages/workspace/WorkspaceResetBankAccountModal.tsx b/src/pages/workspace/WorkspaceResetBankAccountModal.tsx index 4e57c015fc20..7ca73ac5c608 100644 --- a/src/pages/workspace/WorkspaceResetBankAccountModal.tsx +++ b/src/pages/workspace/WorkspaceResetBankAccountModal.tsx @@ -5,8 +5,8 @@ import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; -import CONST from '@src/CONST'; import {cancelResetBankAccount, resetNonUSDBankAccount, resetUSDBankAccount} from '@userActions/BankAccounts'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; From 6c93b7d5f05de4934ef1abe3bff77437440b1f46 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Thu, 4 Sep 2025 00:52:16 +0530 Subject: [PATCH 11/12] fix changed files esLint --- .../USD/BusinessInfo/subSteps/NameBusiness.tsx | 2 +- .../USD/BusinessInfo/subSteps/TaxIdBusiness.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx index ee150131087a..6eb01b1c0e3a 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx @@ -16,7 +16,7 @@ const STEP_FIELDS = [COMPANY_NAME_KEY]; function NameBusiness({onNext, onMove, isEditing}: SubStepProps) { const {translate} = useLocalize(); - const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: true}); const defaultCompanyName = reimbursementAccount?.achData?.companyName ?? ''; const bankAccountID = reimbursementAccount?.achData?.bankAccountID; diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx index ade159288c98..6c1f5041c850 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx @@ -17,7 +17,7 @@ const STEP_FIELDS = [COMPANY_TAX_ID_KEY]; function TaxIdBusiness({onNext, onMove, isEditing}: SubStepProps) { const {translate} = useLocalize(); - const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); + const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: true}); const isLoadingReimbursementAccount = isLoadingOnyxValue(reimbursementAccountResult); // This is default value for the input to be display From 0d817a415dd1b48560b0f557ec40bcdfdc5d6e04 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Sun, 7 Sep 2025 15:54:13 +0530 Subject: [PATCH 12/12] remove unused const --- src/CONST/index.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 55dbb4fc1223..830e6cb80751 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -56,8 +56,6 @@ const keyInputSpace = ' '; // describes if a shortcut key can cause navigation const KEYBOARD_SHORTCUT_NAVIGATION_TYPE = 'NAVIGATION_SHORTCUT'; -const SETUP_STATE = 'SETUP'; - const chatTypes = { POLICY_ANNOUNCE: 'policyAnnounce', POLICY_ADMINS: 'policyAdmins', @@ -5645,15 +5643,6 @@ const CONST = { }, }, - BANK_ACCOUNT_STATE: { - PENDING: 'PENDING', - OPEN: 'OPEN', - DELETED: 'DELETED', - LOCKED: 'LOCKED', - SETUP: SETUP_STATE, - VERIFYING: 'VERIFYING', - }, - // We need to store this server side error in order to not show the blocking screen when the error is for invalid code MERGE_ACCOUNT_INVALID_CODE_ERROR: '401 Not authorized - Invalid validateCode', REIMBURSEMENT_ACCOUNT: {