Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[No QA] Issue New Card Bank Accounts Logic #45069

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ const CONST = {
VERIFICATION_MAX_ATTEMPTS: 7,
STATE: {
VERIFYING: 'VERIFYING',
VALIDATING: 'VALIDATING',
SETUP: 'SETUP',
PENDING: 'PENDING',
OPEN: 'OPEN',
},
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/expensify-card/issue-new',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card/issue-new` as const,
},
WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT: {
route: 'settings/workspaces/:policyID/expensify-card/choose-bank-account',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card/choose-bank-account` as const,
},
WORKSPACE_DISTANCE_RATES: {
route: 'settings/workspaces/:policyID/distance-rates',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/distance-rates` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ const SCREENS = {
RATE_AND_UNIT_UNIT: 'Workspace_RateAndUnit_Unit',
EXPENSIFY_CARD: 'Workspace_ExpensifyCard',
EXPENSIFY_CARD_ISSUE_NEW: 'Workspace_ExpensifyCard_New',
EXPENSIFY_CARD_BANK_ACCOUNT: 'Workspace_ExpensifyCard_BankAccount',
BILLS: 'Workspace_Bills',
INVOICES: 'Workspace_Invoices',
TRAVEL: 'Workspace_Travel',
Expand Down
6 changes: 6 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2637,6 +2637,12 @@ export default {
'We consider a number of factors when calculating your remaining limit: your tenure as a customer, the business-related information you provided during signup, and the available cash in your business bank account. Your remaining limit can fluctuate on a daily basis.',
cashBack: 'Cash back',
cashBackDescription: 'Cash back balance is based on settled monthly Expensify Card spend across your workspace.',
issueNewCard: 'Issue new card',
finishSetup: 'Finish setup',
chooseBankAccount: 'Choose bank account',
chooseExistingBank: 'Choose an existing business bank account to pay your Expensify Card balance, or add a new bank account',
accountEndingIn: 'Account ending in',
addNewBankAccount: 'Add a new bank account',
},
categories: {
deleteCategories: 'Delete categories',
Expand Down
6 changes: 6 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2683,6 +2683,12 @@ export default {
'A la hora de calcular tu límite restante, tenemos en cuenta una serie de factores: su antigüedad como cliente, la información relacionada con tu negocio que nos facilitaste al darte de alta y el efectivo disponible en tu cuenta bancaria comercial. Tu límite restante puede fluctuar a diario.',
cashBack: 'Reembolso',
cashBackDescription: 'El saldo de devolución se basa en el gasto mensual realizado con la tarjeta Expensify en tu espacio de trabajo.',
issueNewCard: '',
finishSetup: 'Terminar configuración',
chooseBankAccount: 'Elegir cuenta bancaria',
chooseExistingBank: 'Elige una cuenta bancaria comercial existente para pagar el saldo de su Tarjeta Expensify o añade una nueva cuenta bancaria.',
accountEndingIn: 'Cuenta terminada en',
addNewBankAccount: 'Añadir nueva cuenta bancaria',
},
categories: {
deleteCategories: 'Eliminar categorías',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.TAX_VALUE]: () => require<ReactComponentModule>('../../../../pages/workspace/taxes/ValuePage').default,
[SCREENS.WORKSPACE.TAX_CREATE]: () => require<ReactComponentModule>('../../../../pages/workspace/taxes/WorkspaceCreateTaxPage').default,
[SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: () => require<ReactComponentModule>('../../../../pages/workspace/card/issueNew/IssueNewCardPage').default,
[SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts').default,
[SCREENS.SETTINGS.SAVE_THE_WORLD]: () => require<ReactComponentModule>('../../../../pages/TeachersUnite/SaveTheWorldPage').default,
[SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_PAYMENT_CURRENCY]: () => require<ReactComponentModule>('../../../../pages/settings/PaymentCard/ChangeCurrency').default,
[SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_BILLING_CURRENCY]: () => require<ReactComponentModule>('../../../../pages/settings/Subscription/PaymentCard/ChangeBillingCurrency').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_VALUE,
SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_INITIAL_VALUE,
],
[SCREENS.WORKSPACE.EXPENSIFY_CARD]: [SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW],
[SCREENS.WORKSPACE.EXPENSIFY_CARD]: [SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW, SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT],
};

export default FULL_SCREEN_TO_RHP_MAPPING;
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: {
path: ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.route,
},
[SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: {
path: ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.route,
},
[SCREENS.WORKSPACE.RATE_AND_UNIT]: {
path: ROUTES.WORKSPACE_RATE_AND_UNIT.route,
},
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,9 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: {
policyID: string;
};
[SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: {
policyID: string;
};
} & ReimbursementAccountNavigatorParamList;

type NewChatNavigatorParamList = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import getBankIcon from '@components/Icon/BankIcons';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {BankName} from '@src/types/onyx/Bank';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type WorkspaceExpensifyCardBankAccountsProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT>;

function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankAccountsProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const [bankAccountsList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);

const policyID = route.params.policyID ?? '-1';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const policyID = route.params.policyID ?? '-1';
const policyID = route?.params?.policyID ?? '-1';


const handleAddBankAccount = () => {
// TODO: call to API - UpdateCardSettlementAccount
Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('new', policyID, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)));
};

const handleSelectBankAccount = () => {
Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID));
};

const renderBankOptions = () => {
mountiny marked this conversation as resolved.
Show resolved Hide resolved
if (!bankAccountsList || isEmptyObject(bankAccountsList)) {
return null;
}

// const eligibleBankAccounts = Object.values(bankAccountsList).filter((bankAccount) => bankAccount.accountData.allowDebit || bankAccount.accountData.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS);
const eligibleBankAccounts = Object.values(bankAccountsList);
Comment on lines +44 to +45
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we omit this check, we could have added it to the mock data if needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be held in #46564


return eligibleBankAccounts.map((bankAccount) => {
const bankName = (bankAccount.accountData?.addressName ?? '') as BankName;
const bankAccountNumber = bankAccount.accountData?.accountNumber ?? '';

const {icon, iconSize, iconStyles} = getBankIcon({bankName, styles});

return (
<MenuItem
title={bankName}
description={`${translate('workspace.expensifyCard.accountEndingIn')} ${bankAccountNumber.slice(-4)}`}
onPress={handleSelectBankAccount}
icon={icon}
iconHeight={iconSize}
iconWidth={iconSize}
iconStyles={iconStyles}
shouldShowRightIcon
displayInDefaultIconColor
/>
);
});
};

return (
<ScreenWrapper
testID={WorkspaceExpensifyCardBankAccounts.displayName}
includeSafeAreaPaddingBottom={false}
shouldEnablePickerAvoiding={false}
>
<HeaderWithBackButton
shouldShowBackButton
onBackButtonPress={() => Navigation.goBack()}
title={translate('workspace.expensifyCard.chooseBankAccount')}
/>
<View style={styles.flex1}>
<Text style={[styles.mh5, styles.mb3]}>{translate('workspace.expensifyCard.chooseExistingBank')}</Text>
{renderBankOptions()}
<MenuItem
icon={Expensicons.Plus}
title={translate('workspace.expensifyCard.addNewBankAccount')}
onPress={handleAddBankAccount}
/>
</View>
</ScreenWrapper>
);
}

WorkspaceExpensifyCardBankAccounts.displayName = 'WorkspaceExpensifyCardBankAccounts';

export default WorkspaceExpensifyCardBankAccounts;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import React, {useCallback} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import FeatureList from '@components/FeatureList';
import type {FeatureListItem} from '@components/FeatureList';
import * as Illustrations from '@components/Icon/Illustrations';
Expand All @@ -14,8 +15,10 @@ import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPol
import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

const expensifyCardFeatures: FeatureListItem[] = [
{
Expand All @@ -40,6 +43,29 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
const styles = useThemeStyles();
const theme = useTheme();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);

const reimbursementAccountStatus = reimbursementAccount?.achData?.state ?? '';

const getTranslationForCta = useCallback(() => {
switch (reimbursementAccountStatus) {
case CONST.BANK_ACCOUNT.STATE.VERIFYING:
case CONST.BANK_ACCOUNT.STATE.SETUP:
case CONST.BANK_ACCOUNT.STATE.VALIDATING:
return 'workspace.expensifyCard.finishSetup';
default:
return 'workspace.expensifyCard.issueNewCard';
}
}, [reimbursementAccountStatus]);

const startFlow = useCallback(() => {
if (isEmptyObject(bankAccountList)) {
Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('', policy?.id, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policy?.id ?? '-1')));
} else {
Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.getRoute(policy?.id ?? '-1'));
}
}, [bankAccountList, policy?.id]);

return (
<WorkspacePageWithSections
Expand All @@ -55,9 +81,9 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
menuItems={expensifyCardFeatures}
title={translate('workspace.moreFeatures.expensifyCard.feed.title')}
subtitle={translate('workspace.moreFeatures.expensifyCard.feed.subTitle')}
ctaText={translate('workspace.moreFeatures.expensifyCard.feed.ctaTitle')}
ctaText={translate(getTranslationForCta())}
ctaAccessibilityLabel={translate('workspace.moreFeatures.expensifyCard.feed.ctaTitle')}
onCtaPress={() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policy?.id ?? '-1'))}
onCtaPress={startFlow}
illustrationBackgroundColor={theme.fallbackIconColor}
illustration={Illustrations.ExpensifyCardIllustration}
illustrationStyle={styles.expensifyCardIllustrationContainer}
Expand Down
Loading