diff --git a/src/components/Navigation/DebugTabView.tsx b/src/components/Navigation/DebugTabView.tsx index 8c701e6b3b68e..95ecf5ec7d0d1 100644 --- a/src/components/Navigation/DebugTabView.tsx +++ b/src/components/Navigation/DebugTabView.tsx @@ -157,7 +157,7 @@ function DebugTabView({selectedTab, chatTabBrickRoad}: DebugTabViewProps) { } }, [selectedTab, chatTabBrickRoad, orderedReportIDs, reportAttributes, status, reimbursementAccount, policyIDWithErrors]); - if (!([NAVIGATION_TABS.INBOX, NAVIGATION_TABS.SETTINGS, NAVIGATION_TABS.WORKSPACES] as string[]).includes(selectedTab ?? '') || !indicator) { + if (!([NAVIGATION_TABS.INBOX, NAVIGATION_TABS.SETTINGS, NAVIGATION_TABS.WORKSPACES] as string[]).includes(selectedTab ?? '') || !indicator || !message) { return null; } diff --git a/src/hooks/useNavigationTabBarIndicatorChecks.ts b/src/hooks/useNavigationTabBarIndicatorChecks.ts index 5e6d8418e6436..63752960548ac 100644 --- a/src/hooks/useNavigationTabBarIndicatorChecks.ts +++ b/src/hooks/useNavigationTabBarIndicatorChecks.ts @@ -72,7 +72,7 @@ function useNavigationTabBarIndicatorChecks(): NavigationTabBarChecksResult { // we only care if a single error / info condition exists anywhere. const accountChecks: Partial> = { [CONST.INDICATOR_STATUS.HAS_USER_WALLET_ERRORS]: Object.keys(userWallet?.errors ?? {}).length > 0, - [CONST.INDICATOR_STATUS.HAS_PAYMENT_METHOD_ERROR]: hasPaymentMethodError(bankAccountList, fundList, allCards), + [CONST.INDICATOR_STATUS.HAS_PAYMENT_METHOD_ERROR]: hasPaymentMethodError(bankAccountList, fundList, allCards, session, policies), [CONST.INDICATOR_STATUS.HAS_SUBSCRIPTION_ERRORS]: hasSubscriptionRedDotError( stripeCustomerId, retryBillingSuccessful, diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index a860f5b734a25..e5ba1ada4034d 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -1,5 +1,5 @@ import type {RefObject} from 'react'; -import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type {KYCWallRef} from '@components/KYCWall/types'; @@ -18,6 +18,7 @@ import * as CardUtils from '@libs/CardUtils'; import GoogleTagManager from '@libs/GoogleTagManager'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; +import {isPolicyUser} from '@libs/PolicyUtils'; import {getCardForSubscriptionBilling} from '@libs/SubscriptionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -25,7 +26,9 @@ import type {Route} from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/AddPaymentCardForm'; import type {BankAccountList, CardList, FundList} from '@src/types/onyx'; import type PaymentMethod from '@src/types/onyx/PaymentMethod'; +import type Policy from '@src/types/onyx/Policy'; import type {OnyxData} from '@src/types/onyx/Request'; +import type Session from '@src/types/onyx/Session'; import type {FilterMethodPaymentType} from '@src/types/onyx/WalletTransfer'; /** @@ -409,13 +412,33 @@ function dismissSuccessfulTransferBalancePage() { } /** - * Looks through each payment method to see if there is an existing error - * + * Looks through each payment method to see if there is an existing error. + * When session and policies are provided, card list errors are only counted if the current user + * is a member of that card's workspace (for company cards) or always counted for personal cards. + * Only cards with non-empty errors are considered (error cards). */ -function hasPaymentMethodError(bankList: OnyxEntry, fundList: OnyxEntry, cardList: OnyxEntry): boolean { - const combinedPaymentMethods = {...bankList, ...fundList, ...cardList}; - - return Object.values(combinedPaymentMethods).some((item) => Object.keys(item.errors ?? {}).length); +function hasPaymentMethodError( + bankList: OnyxEntry, + fundList: OnyxEntry, + cardList: OnyxEntry, + session?: OnyxEntry, + policies?: OnyxCollection, +): boolean { + const hasBankOrFundError = Object.values({...(bankList ?? {}), ...(fundList ?? {})}).some((item) => Object.keys(item?.errors ?? {}).length > 0); + const currentUserLogin = session?.email; + const cardsWithErrors = Object.values(cardList ?? {}).filter((card) => Object.keys(card?.errors ?? {}).length > 0); + + const policyList = Object.values(policies ?? {}).filter(Boolean); + const hasRelevantCardError = cardsWithErrors.some((card) => { + if (CardUtils.isPersonalCard(card)) { + return true; + } + const workspaceAccountID = Number(card?.fundID); + const policy = policyList.find((p) => p?.workspaceAccountID === workspaceAccountID); + return !!policy && isPolicyUser(policy, currentUserLogin); + }); + // If there is card with errors, we should display the RBR if user is a member of the workspace. + return hasRelevantCardError || hasBankOrFundError; } type PaymentListKey = diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index ca950ea665e1f..664270bf55311 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -159,18 +159,15 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr const shouldDisplayLHB = !shouldUseNarrowLayout; const { - all: {shouldShowRBR}, personalCard: {shouldShowRBR: shouldShowRBRForPersonalCard}, } = useCardFeedErrors(); - const hasPendingCardAction = hasPendingExpensifyCardAction(allCards, privatePersonalDetails); let walletBrickRoadIndicator; if ( - hasPaymentMethodError(bankAccountList, fundList, allCards) || + hasPaymentMethodError(bankAccountList, fundList, allCards, session, policies) || !isEmptyObject(userWallet?.errors) || !isEmptyObject(walletTerms?.errors) || !isEmptyObject(unsharedBankAccount?.errors) || - shouldShowRBR || shouldShowRBRForPersonalCard ) { walletBrickRoadIndicator = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;