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: 4 additions & 4 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ const ROUTES = {
return `bank-account/enter-signer-info?policyID=${policyID}&bankAccountID=${bankAccountID}&isCompleted=${isCompleted}` as const;
},
},
BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT: {
route: 'bank-account/connect-existing-business-bank-account',
getRoute: (policyID: string) => `bank-account/connect-existing-business-bank-account?policyID=${policyID}` as const,
},
PUBLIC_CONSOLE_DEBUG: {
route: 'troubleshoot/console',

Expand Down Expand Up @@ -1550,10 +1554,6 @@ const ROUTES = {
return `workspaces/${policyID}/workflows` as const;
},
},
WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT: {
route: 'workspaces/:policyID/workflows/connect-account',
getRoute: (policyID: string) => `workspaces/${policyID}/workflows/connect-account` as const,
},
WORKSPACE_WORKFLOWS_APPROVALS_NEW: {
route: 'workspaces/:policyID/workflows/approvals/new',
getRoute: (policyID: string) => `workspaces/${policyID}/workflows/approvals/new` as const,
Expand Down
2 changes: 1 addition & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,6 @@ const SCREENS = {
WORKFLOWS_APPROVALS_APPROVER: 'Workspace_Workflows_Approvals_Approver',
WORKFLOWS_AUTO_REPORTING_FREQUENCY: 'Workspace_Workflows_Auto_Reporting_Frequency',
WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET: 'Workspace_Workflows_Auto_Reporting_Monthly_Offset',
WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT: 'Workspace_Workflows_Connect_Existing_Bank_Account',
DESCRIPTION: 'Workspace_Overview_Description',
SHARE: 'Workspace_Overview_Share',
NAME: 'Workspace_Overview_Name',
Expand Down Expand Up @@ -740,6 +739,7 @@ const SCREENS = {
ENABLE_PAYMENTS_ROOT: 'EnablePayments_Root',
ADD_PERSONAL_BANK_ACCOUNT_ROOT: 'AddPersonalBankAccount_Root',
REIMBURSEMENT_ACCOUNT_ROOT: 'Reimbursement_Account_Root',
CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT: 'Connect_Existing_Business_Bank_Account_Root',
WALLET_STATEMENT_ROOT: 'WalletStatement_Root',
SIGN_IN_ROOT: 'SignIn_Root',
DETAILS_ROOT: 'Details_Root',
Expand Down
36 changes: 35 additions & 1 deletion src/components/KYCWall/BaseKYCWall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import getClickedTargetLocation from '@libs/getClickedTargetLocation';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import {hasExpensifyPaymentMethod} from '@libs/PaymentUtils';
import {hasInProgressVBBA} from '@libs/ReimbursementAccountUtils';
import {getBankAccountRoute, isExpenseReport as isExpenseReportReportUtils, isIOUReport} from '@libs/ReportUtils';
import {getEligibleExistingBusinessBankAccounts} from '@libs/WorkflowUtils';
import {kycWallRef} from '@userActions/PaymentMethods';
import {createWorkspaceFromIOUPayment} from '@userActions/Policy/Policy';
import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount';
import {setKYCWallSource} from '@userActions/Wallet';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -56,6 +59,7 @@ function KYCWall({
const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: true});
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, {canBeMissing: true});
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});
const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});

const {formatPhoneNumber} = useLocalize();

Expand Down Expand Up @@ -108,6 +112,11 @@ function KYCWall({
setPositionAddPaymentMenu(position);
}, [getAnchorPosition]);

const canLinkExistingBusinessBankAccount = useCallback(
Comment thread
MrMuzyk marked this conversation as resolved.
(policy?: Policy) => policy !== undefined && getEligibleExistingBusinessBankAccounts(bankAccountList, policy.outputCurrency).length > 0,
[bankAccountList],
);

const selectPaymentMethod = useCallback(
(paymentMethod?: PaymentMethod, policy?: Policy) => {
if (paymentMethod) {
Expand Down Expand Up @@ -153,11 +162,36 @@ function KYCWall({
Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(policyID));
return;
}

// If user has a setup in progress we do not show them the option to connect existing account
const isNonUSDWorkspace = policy?.outputCurrency !== CONST.CURRENCY.USD;
if (policy !== undefined && hasInProgressVBBA(reimbursementAccount?.achData, isNonUSDWorkspace, reimbursementAccountDraft?.country ?? '')) {
navigateToBankAccountRoute(policy.id);
return;
}

if (policy !== undefined && canLinkExistingBusinessBankAccount(policy)) {
Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(policy?.id));
return;
}

const bankAccountRoute = addBankAccountRoute ?? getBankAccountRoute(chatReport);
Navigation.navigate(bankAccountRoute);
}
},
[addBankAccountRoute, addDebitCardRoute, chatReport, iouReport, onSelectPaymentMethod, formatPhoneNumber, lastPaymentMethod, policies],
[
onSelectPaymentMethod,
iouReport,
addDebitCardRoute,
reimbursementAccount?.achData,
reimbursementAccountDraft?.country,
canLinkExistingBusinessBankAccount,
addBankAccountRoute,
chatReport,
policies,
formatPhoneNumber,
lastPaymentMethod,
],
);

/**
Expand Down
21 changes: 18 additions & 3 deletions src/components/SettlementButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils';
import {setPersonalBankAccountContinueKYCOnSuccess} from '@userActions/BankAccounts';
import {approveMoneyRequest} from '@userActions/IOU';
import {getPaymentMethods} from '@userActions/PaymentMethods';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand Down Expand Up @@ -131,6 +132,13 @@ function SettlementButton({
const formattedPaymentMethods = formatPaymentMethods(bankAccountList ?? {}, fundList ?? {}, styles);
const hasIntentToPay = ((formattedPaymentMethods.length === 1 && isIOUReport(iouReport)) || !!policy?.achAccount) && !lastPaymentMethod;

useEffect(() => {
if (isOffline) {
return;
}
getPaymentMethods();
}, [isOffline]);

useEffect(() => {
if (isLoadingLastPaymentMethod) {
return;
Expand Down Expand Up @@ -428,7 +436,9 @@ function SettlementButton({
return lastPaymentPolicy.name;
}

const bankAccountToDisplay = hasIntentToPay ? (formattedPaymentMethods.at(0) as BankAccount) : bankAccount;
const bankAccountToDisplay = hasIntentToPay
? ((formattedPaymentMethods.find((method) => method.methodID === policy?.achAccount?.bankAccountID) ?? formattedPaymentMethods.at(0)) as BankAccount)
: bankAccount;
if (lastPaymentMethod === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || (hasIntentToPay && isInvoiceReportUtil(iouReport))) {
if (!personalBankAccountList.length) {
return;
Expand All @@ -446,6 +456,12 @@ function SettlementButton({
return;
}

if (bankAccountToDisplay?.accountData?.accountNumber) {
return translate('paymentMethodList.bankAccountLastFour', {
lastFour: bankAccountToDisplay.accountData.accountNumber.slice(-4),
});
}

return translate('paymentMethodList.bankAccountLastFour', {lastFour: bankAccountToDisplay?.accountData?.accountNumber?.slice(-4)});
}

Expand All @@ -468,8 +484,7 @@ function SettlementButton({

const isPaymentMethod = Object.values(CONST.PAYMENT_METHODS).includes(selectedOption as PaymentMethod);
const shouldSelectPaymentMethod = (isPaymentMethod ?? lastPaymentPolicy ?? !isEmpty(latestBankItem)) && !shouldShowApproveButton && !shouldHidePaymentOptions;
const selectedPolicy = activeAdminPolicies.find((activePolicy) => activePolicy.id === selectedOption);

const selectedPolicy = activeAdminPolicies.find((activePolicy) => activePolicy.id === policyIDKey);
if (!!selectedPolicy || shouldSelectPaymentMethod) {
selectPaymentMethod(event, triggerKYCFlow, selectedOption as PaymentMethod, selectedPolicy);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_CUSTOMERS_DISPLAYED_AS]: () =>
require<ReactComponentModule>('../../../../pages/workspace/accounting/qbd/import/QuickbooksDesktopCustomersDisplayedAsPage').default,
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_ITEMS]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbd/import/QuickbooksDesktopItemsPage').default,
[SCREENS.WORKSPACE.WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT]: () =>
require<ReactComponentModule>('../../../../pages/workspace/workflows/WorkspaceWorkflowsConnectExistingBankAccountPage').default,
[SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT]: () => require<ReactComponentModule>('@pages/workspace/ConnectExistingBusinessBankAccountPage').default,
[SCREENS.REIMBURSEMENT_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/ReimbursementAccountPage').default,
[SCREENS.REIMBURSEMENT_ACCOUNT_ENTER_SIGNER_INFO]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/EnterSignerInfo').default,
[SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/ReportCardLostPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET,
SCREENS.WORKSPACE.WORKFLOWS_PAYER,
SCREENS.WORKSPACE.WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT,
],
[SCREENS.WORKSPACE.ACCOUNTING.ROOT]: [
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_IMPORT,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,8 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
[SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_INITIAL_VALUE]: {
path: ROUTES.WORKSPACE_EDIT_REPORT_FIELDS_INITIAL_VALUE.route,
},
[SCREENS.WORKSPACE.WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT]: {
path: ROUTES.WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT.route,
[SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT]: {
path: ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.route,
exact: true,
},
[SCREENS.REIMBURSEMENT_ACCOUNT]: {
Expand Down
10 changes: 7 additions & 3 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,12 @@ type ReimbursementAccountEnterSignerInfoNavigatorParamList = {
};
};

type ConnectExistingBankAccountNavigatorParamList = {
[SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT]: {
policyID: string;
};
};

type WalletStatementNavigatorParamList = {
[SCREENS.WALLET_STATEMENT_ROOT]: {
/** The statement year and month as one string, i.e. 202110 */
Expand Down Expand Up @@ -1989,9 +1995,6 @@ type WorkspaceSplitNavigatorParamList = {
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: {
policyID: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT]: {
policyID: string;
};
[SCREENS.WORKSPACE.INVOICES]: {
policyID: string;
};
Expand Down Expand Up @@ -2435,6 +2438,7 @@ export type {
ReferralDetailsNavigatorParamList,
ReimbursementAccountNavigatorParamList,
ReimbursementAccountEnterSignerInfoNavigatorParamList,
ConnectExistingBankAccountNavigatorParamList,
NewReportWorkspaceSelectionNavigatorParamList,
ReportDescriptionNavigatorParamList,
ReportDetailsNavigatorParamList,
Expand Down
13 changes: 11 additions & 2 deletions src/pages/settings/Wallet/PaymentMethodList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ type PaymentMethodListProps = {
/** Type of payment method to filter by */
filterType?: ValueOf<typeof CONST.BANK_ACCOUNT.TYPE>;

/* Currency of payment method to filter by */
filterCurrency?: string;

/** Whether to show the default badge for the payment method */
shouldHideDefaultBadge?: boolean;
};
Expand Down Expand Up @@ -185,6 +188,7 @@ function PaymentMethodList({
onAddBankAccountPress = () => {},
itemIconRight,
filterType,
filterCurrency,
shouldHideDefaultBadge = false,
}: PaymentMethodListProps) {
const styles = useThemeStyles();
Expand Down Expand Up @@ -322,8 +326,12 @@ function PaymentMethodList({
);
}

if (filterType) {
combinedPaymentMethods = combinedPaymentMethods.filter((paymentMethod) => (paymentMethod as BankAccount).accountData?.type === filterType);
if (filterType ?? filterCurrency) {
combinedPaymentMethods = combinedPaymentMethods.filter((paymentMethod) => {
const account = paymentMethod as BankAccount;

return (!!filterType && account.accountData?.type === filterType) || (!!filterCurrency && account.bankCurrency === filterCurrency);
});
}

combinedPaymentMethods = combinedPaymentMethods.map((paymentMethod) => {
Expand Down Expand Up @@ -362,6 +370,7 @@ function PaymentMethodList({
styles,
isOffline,
filterType,
filterCurrency,
isLoadingCardList,
cardList,
illustrations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,50 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@navigation/Navigation';
import type {PlatformStackScreenProps} from '@navigation/PlatformStackNavigation/types';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
import type {ConnectExistingBankAccountNavigatorParamList} from '@navigation/types';
import PaymentMethodList from '@pages/settings/Wallet/PaymentMethodList';
import type {PaymentMethodPressHandlerParams} from '@pages/settings/Wallet/WalletPage/types';
import {setWorkspaceReimbursement} from '@userActions/Policy/Policy';
import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';

type WorkspaceWorkflowsConnectExistingBankAccountPageProps = PlatformStackScreenProps<WorkspaceSplitNavigatorParamList, typeof SCREENS.WORKSPACE.WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT>;
type ConnectExistingBusinessBankAccountPageProps = PlatformStackScreenProps<ConnectExistingBankAccountNavigatorParamList, typeof SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT>;

function WorkspaceWorkflowsConnectExistingBankAccountPage({route}: WorkspaceWorkflowsConnectExistingBankAccountPageProps) {
function ConnectExistingBusinessBankAccountPage({route}: ConnectExistingBusinessBankAccountPageProps) {
const policyID = route.params?.policyID;
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {canBeMissing: false});
const policyName = policy?.name ?? '';
const policyCurrency = policy?.outputCurrency ?? '';
const {shouldUseNarrowLayout} = useResponsiveLayout();

const styles = useThemeStyles();
const {translate} = useLocalize();

const handleAddBankAccountPress = () => {
navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID));
navigateToBankAccountRoute(policyID);
};

const handleItemPress = ({methodID}: PaymentMethodPressHandlerParams) => {
if (policyID === undefined) {
return;
}

const newReimburserEmail = policy?.achAccount?.reimburser ?? policy?.owner ?? '';
setWorkspaceReimbursement({
policyID: route.params.policyID,
policyID,
reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,
bankAccountID: methodID ?? CONST.DEFAULT_NUMBER_ID,
reimburserEmail: newReimburserEmail,
});
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)));
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.closeRHPFlow());
};

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={WorkspaceWorkflowsConnectExistingBankAccountPage.displayName}
testID={ConnectExistingBusinessBankAccountPage.displayName}
>
<HeaderWithBackButton
title={translate('bankAccount.addBankAccount')}
Expand All @@ -65,13 +69,14 @@ function WorkspaceWorkflowsConnectExistingBankAccountPage({route}: WorkspaceWork
listItemStyle={shouldUseNarrowLayout ? styles.ph5 : styles.ph8}
itemIconRight={Expensicons.ArrowRight}
filterType={CONST.BANK_ACCOUNT.TYPE.BUSINESS}
filterCurrency={policyCurrency}
shouldHideDefaultBadge
/>
</ScrollView>
</ScreenWrapper>
);
}

WorkspaceWorkflowsConnectExistingBankAccountPage.displayName = 'WorkspaceWorkflowsConnectExistingBankAccountPage';
ConnectExistingBusinessBankAccountPage.displayName = 'ConnectExistingBusinessBankAccountPage';

export default WorkspaceWorkflowsConnectExistingBankAccountPage;
export default ConnectExistingBusinessBankAccountPage;
2 changes: 1 addition & 1 deletion src/pages/workspace/WorkspaceOverviewCurrencyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function WorkspaceOverviewCurrencyPage({policy}: WorkspaceOverviewCurrencyPagePr
if (isCurrencySupportedForGlobalReimbursement(item.currencyCode as CurrencyType, isBetaEnabled(CONST.BETAS.GLOBAL_REIMBURSEMENTS_ON_ND))) {
const hasValidExistingAccounts = getEligibleExistingBusinessBankAccounts(bankAccountList, item.currencyCode).length > 0;
if (hasValidExistingAccounts) {
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT.getRoute(policy.id));
Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(policy.id));
return;
}
navigateToBankAccountRoute(policy.id, ROUTES.WORKSPACE_WORKFLOWS.getRoute(policy.id), {forceReplace: true});
Expand Down
4 changes: 2 additions & 2 deletions src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
updateGeneralSettings(policy.id, policy.name, CONST.CURRENCY.USD);
const hasValidExistingUSDAccounts = getEligibleExistingBusinessBankAccounts(bankAccountList, CONST.CURRENCY.USD).length > 0;
if (hasValidExistingUSDAccounts) {
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT.getRoute(route.params.policyID));
Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(route.params.policyID));
} else {
navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID));
}
Expand Down Expand Up @@ -308,7 +308,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
}

if (!shouldShowBankAccount && hasValidExistingAccounts && !shouldShowContinueModal) {
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_EXISTING_BANK_ACCOUNT.getRoute(route.params.policyID));
Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(route.params.policyID));
return;
}

Expand Down
Loading