Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/pages/settings/Wallet/PaymentMethodList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ type PaymentMethodListProps = {
/** Whether the right icon should be shown in PaymentMethodItem */
shouldShowRightIcon?: boolean;

/** Whether the we should skip default account validation when adding bank account */
shouldSkipDefaultAccountValidation?: boolean;

/** What to do when a menu item is pressed */
onPress: PaymentMethodPressHandler | CardPressHandler;

Expand Down Expand Up @@ -139,6 +142,7 @@ function PaymentMethodList({
onPress,
shouldShowAddBankAccount = true,
shouldShowAssignedCards = false,
shouldSkipDefaultAccountValidation = false,
onListContentSizeChange = () => {},
style = {},
listItemStyle = {},
Expand Down Expand Up @@ -390,7 +394,7 @@ function PaymentMethodList({
]);

const onPressItem = useCallback(() => {
if (!isUserValidated) {
if (!isUserValidated && !shouldSkipDefaultAccountValidation) {
const path = Navigation.getActiveRoute();
if (path.includes(ROUTES.WORKSPACES_LIST.route) && policyID) {
Navigation.navigate(ROUTES.WORKSPACE_INVOICES_VERIFY_ACCOUNT.getRoute(policyID));
Expand All @@ -400,7 +404,7 @@ function PaymentMethodList({
return;
}
onAddBankAccountPress();
}, [isUserValidated, onAddBankAccountPress, policyID]);
}, [isUserValidated, onAddBankAccountPress, policyID, shouldSkipDefaultAccountValidation]);

const renderListFooterComponent = useCallback(
() => (
Expand Down
56 changes: 55 additions & 1 deletion src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {RefObject} from 'react';
import React, {useCallback, useRef, useState} from 'react';
import React, {useCallback, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import type {TupleToUnion} from 'type-fest';
import ConfirmModal from '@components/ConfirmModal';
import MenuItem from '@components/MenuItem';
import Popover from '@components/Popover';
Expand All @@ -10,12 +11,17 @@
import useOnyx from '@hooks/useOnyx';
import usePaymentMethodState from '@hooks/usePaymentMethodState';
import type {FormattedSelectedPaymentMethod} from '@hooks/usePaymentMethodState/types';
import usePermissions from '@hooks/usePermissions';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {isCurrencySupportedForGlobalReimbursement, setIsForcedToChangeCurrency} from '@libs/actions/Policy/Policy';
import {navigateToBankAccountRoute} from '@libs/actions/ReimbursementAccount';
import getClickedTargetLocation from '@libs/getClickedTargetLocation';
import Navigation from '@libs/Navigation/Navigation';
import {formatPaymentMethods, getPaymentMethodDescription} from '@libs/PaymentUtils';
import {hasInProgressVBBA} from '@libs/ReimbursementAccountUtils';
import {getEligibleExistingBusinessBankAccounts} from '@libs/WorkflowUtils';
import PaymentMethodList from '@pages/settings/Wallet/PaymentMethodList';
import type {PaymentMethodPressHandlerParams} from '@pages/settings/Wallet/WalletPage/types';
import variables from '@styles/variables';
Expand All @@ -32,6 +38,8 @@
policyID: string;
};

type CurrencyType = TupleToUnion<typeof CONST.DIRECT_REIMBURSEMENT_CURRENCIES>;

// TODO: can be refactored to use ThreeDotsMenu component instead handling the popover and positioning
function WorkspaceInvoiceVBASection({policyID}: WorkspaceInvoiceVBASectionProps) {
const icons = useMemoizedLazyExpensifyIcons(['Star', 'Trashcan'] as const);
Expand All @@ -57,6 +65,32 @@
const isPopoverBottomMount = anchorPosition.anchorPositionTop === 0 || shouldUseNarrowLayout;
const shouldShowMakeDefaultButton = !paymentMethod.isSelectedPaymentMethodDefault;
const transferBankAccountID = policy?.invoice?.bankAccount?.transferBankAccountID ?? CONST.DEFAULT_NUMBER_ID;
const {isBetaEnabled} = usePermissions();
const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: true});
const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
const [isUpdateWorkspaceCurrencyModalOpen, setIsUpdateWorkspaceCurrencyModalOpen] = useState(false);

const hasValidExistingAccounts = getEligibleExistingBusinessBankAccounts(bankAccountList, policy?.outputCurrency).length > 0;
const isSupportedGlobalReimbursement = isCurrencySupportedForGlobalReimbursement((policy?.outputCurrency ?? '') as CurrencyType);

const isNonUSDWorkspace = policy?.outputCurrency !== CONST.CURRENCY.USD;
const achData = reimbursementAccount?.achData;
const nonUSDCountryDraftValue = reimbursementAccountDraft?.country ?? '';

const shouldShowContinueModal = useMemo(() => {
return hasInProgressVBBA(achData, isNonUSDWorkspace, nonUSDCountryDraftValue);
}, [achData, isNonUSDWorkspace, nonUSDCountryDraftValue]);

const confirmCurrencyChangeAndHideModal = useCallback(() => {
if (!policy) {
return;
}

setIsUpdateWorkspaceCurrencyModalOpen(false);

setIsForcedToChangeCurrency(true);
Navigation.navigate(ROUTES.WORKSPACE_OVERVIEW_CURRENCY.getRoute(policy.id));
}, [bankAccountList, isBetaEnabled, policy]);

Check warning on line 93 in src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useCallback has unnecessary dependencies: 'bankAccountList' and 'isBetaEnabled'. Either exclude them or remove the dependency array

/**
* Set position of the payment menu
Expand Down Expand Up @@ -142,6 +176,15 @@
setShouldShowDefaultDeleteMenu(false);
return;
}
if (!isSupportedGlobalReimbursement) {
setIsUpdateWorkspaceCurrencyModalOpen(true);
return;
}

if (hasValidExistingAccounts && !shouldShowContinueModal) {
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT.getRoute(policyID));
return;
}
navigateToBankAccountRoute(policyID, ROUTES.WORKSPACE_INVOICES.getRoute(policyID));
};

Expand All @@ -156,6 +199,7 @@
<PaymentMethodList
onPress={paymentMethodPressed}
onAddBankAccountPress={onAddBankAccountPress}
shouldSkipDefaultAccountValidation={!isSupportedGlobalReimbursement}
invoiceTransferBankAccountID={transferBankAccountID}
activePaymentMethodID={transferBankAccountID}
actionPaymentMethodType={shouldShowDefaultDeleteMenu ? paymentMethod.selectedPaymentMethodType : ''}
Expand Down Expand Up @@ -232,6 +276,16 @@
danger
onModalHide={resetSelectedPaymentMethodData}
/>
<ConfirmModal
title={translate('workspace.bankAccount.workspaceCurrency')}
isVisible={isUpdateWorkspaceCurrencyModalOpen}
onConfirm={confirmCurrencyChangeAndHideModal}
onCancel={() => setIsUpdateWorkspaceCurrencyModalOpen(false)}
prompt={translate('workspace.bankAccount.updateCurrencyPrompt')}
confirmText={translate('workspace.bankAccount.updateToUSD')}
cancelText={translate('common.cancel')}
danger
/>
</Section>
);
}
Expand Down
Loading