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
6 changes: 4 additions & 2 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ const CONST = {
},
STEP: {
// In the order they appear in the VBA flow
COUNTRY: 'CountryStep',
BANK_ACCOUNT: 'BankAccountStep',
REQUESTOR: 'RequestorStep',
COMPANY: 'CompanyStep',
Expand All @@ -484,12 +485,12 @@ const CONST = {
VALIDATION: 'ValidationStep',
ENABLE: 'EnableStep',
},
STEP_NAMES: ['1', '2', '3', '4', '5'],
STEPS_HEADER_HEIGHT: 40,
STEP_NAMES: ['1', '2', '3', '4', '5', '6'],
SUBSTEP: {
MANUAL: 'manual',
PLAID: 'plaid',
},
STEPS_HEADER_HEIGHT: 40,
VERIFICATIONS: {
ERROR_MESSAGE: 'verifications.errorMessage',
THROTTLED: 'verifications.throttled',
Expand All @@ -508,6 +509,7 @@ const CONST = {
SETUP_TYPE: {
MANUAL: 'manual',
PLAID: 'plaid',
NONE: '',
},
REGEX: {
US_ACCOUNT_NUMBER: /^[0-9]{4,17}$/,
Expand Down
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ const ONYXKEYS = {
/** Stores Workspace ID that will be tied to reimbursement account during setup */
REIMBURSEMENT_ACCOUNT_WORKSPACE_ID: 'reimbursementAccountWorkspaceID',

/** Stores the bank connection type user wants to set up before validation code modal */
REIMBURSEMENT_ACCOUNT_OPTION_PRESSED: 'reimbursementAccountOptionPressed',

/** Set when we are loading payment methods */
IS_LOADING_PAYMENT_METHODS: 'isLoadingPaymentMethods',

Expand Down Expand Up @@ -1108,6 +1111,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.PURCHASE_LIST]: OnyxTypes.PurchaseList;
[ONYXKEYS.PERSONAL_BANK_ACCOUNT]: OnyxTypes.PersonalBankAccount;
[ONYXKEYS.REIMBURSEMENT_ACCOUNT]: OnyxTypes.ReimbursementAccount;
[ONYXKEYS.REIMBURSEMENT_ACCOUNT_OPTION_PRESSED]: ValueOf<typeof CONST.BANK_ACCOUNT.SETUP_TYPE>;
[ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE]: string | number;
[ONYXKEYS.FREQUENTLY_USED_EMOJIS]: OnyxTypes.FrequentlyUsedEmoji[];
[ONYXKEYS.REIMBURSEMENT_ACCOUNT_WORKSPACE_ID]: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,30 @@ import {clearErrors} from '@userActions/FormActions';
import ONYXKEYS from '@src/ONYXKEYS';
import Confirmation from './subSteps/Confirmation';

type CountryProps = {
type CountryFullStepProps = {
/** Handles back button press */
onBackButtonPress: () => void;

/** Array of step names */
stepNames: readonly string[];

/** Handles submit button press */
onSubmit: () => void;

/** ID of current policy */
policyID: string | undefined;

/** Array of step names */
stepNames?: readonly string[];
};

type CountryStepProps = {
type CountrySubStepProps = {
/** ID of current policy */
policyID: string | undefined;
} & SubStepProps;

const bodyContent: Array<ComponentType<CountryStepProps>> = [Confirmation];
const bodyContent: Array<ComponentType<CountrySubStepProps>> = [Confirmation];

function Country({onBackButtonPress, onSubmit, policyID, stepNames}: CountryProps) {
function CountryFullStep({onBackButtonPress, stepNames, onSubmit, policyID}: CountryFullStepProps) {
const {translate} = useLocalize();

const submit = () => {
onSubmit();
};

const {
componentToRender: SubStep,
isEditing,
Expand All @@ -44,7 +40,7 @@ function Country({onBackButtonPress, onSubmit, policyID, stepNames}: CountryProp
prevScreen,
moveTo,
goToTheLastStep,
} = useSubStep<CountryStepProps>({bodyContent, startFrom: 0, onFinished: submit});
} = useSubStep<CountrySubStepProps>({bodyContent, startFrom: 0, onFinished: onSubmit});

const handleBackButtonPress = () => {
clearErrors(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM);
Expand All @@ -62,7 +58,7 @@ function Country({onBackButtonPress, onSubmit, policyID, stepNames}: CountryProp

return (
<InteractiveStepWrapper
wrapperID={Country.displayName}
wrapperID={CountryFullStep.displayName}
handleBackButtonPress={handleBackButtonPress}
headerTitle={translate('countryStep.confirmCurrency')}
stepNames={stepNames}
Expand All @@ -78,6 +74,6 @@ function Country({onBackButtonPress, onSubmit, policyID, stepNames}: CountryProp
);
}

Country.displayName = 'Country';
CountryFullStep.displayName = 'Country';

export default Country;
export default CountryFullStep;
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import type {SubStepProps} from '@hooks/useSubStep/types';
import useThemeStyles from '@hooks/useThemeStyles';
import mapCurrencyToCountry from '@libs/mapCurrencyToCountry';
import Navigation from '@libs/Navigation/Navigation';
import {getFieldRequiredErrors} from '@libs/ValidationUtils';
import mapCurrencyToCountry from '@pages/ReimbursementAccount/utils/mapCurrencyToCountry';
import {clearErrors, setDraftValues} from '@userActions/FormActions';
import {setIsComingFromGlobalReimbursementsFlow} from '@userActions/Policy/Policy';
import CONST from '@src/CONST';
Expand All @@ -32,8 +32,7 @@ function Confirmation({onNext, policyID}: ConfirmationStepProps) {
const styles = useThemeStyles();
const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});

const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {canBeMissing: false});
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {canBeMissing: true});
const currency = policy?.outputCurrency ?? '';

const shouldAllowChange = currency === CONST.CURRENCY.EUR;
Expand Down Expand Up @@ -97,8 +96,9 @@ function Confirmation({onNext, policyID}: ConfirmationStepProps) {
style={[styles.label]}
onPress={handleSettingsPress}
>
{translate('common.settings').toLowerCase()}.
{translate('common.settings').toLowerCase()}
</TextLink>
.
</Text>
<InputWrapper
InputComponent={PushRowWithModal}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ACHContractStepProps} from '@src/types/form/ReimbursementAccountForm';

type AcceptACHContractForBankAccount = ACHContractStepProps & {bankAccountID: number; policyID: string};
type AcceptACHContractForBankAccount = ACHContractStepProps & {bankAccountID: number; policyID: string | undefined};

export default AcceptACHContractForBankAccount;
1 change: 1 addition & 0 deletions src/libs/ReimbursementAccountUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function getRouteForCurrentStep(currentStep: ReimbursementAccountStep): Reimburs
case CONST.BANK_ACCOUNT.STEP.ENABLE:
return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.ENABLE;
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
case CONST.BANK_ACCOUNT.STEP.COUNTRY:
Comment thread
MrMuzyk marked this conversation as resolved.
default:
return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW;
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/BankAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ function updateBeneficialOwnersForBankAccount(bankAccountID: number, params: Par
* Accept the ACH terms and conditions and verify the accuracy of the information provided
* @param params - Verification step form params
*/
function acceptACHContractForBankAccount(bankAccountID: number, params: ACHContractStepProps, policyID: string) {
function acceptACHContractForBankAccount(bankAccountID: number, params: ACHContractStepProps, policyID: string | undefined) {
API.write(
WRITE_COMMANDS.ACCEPT_ACH_CONTRACT_FOR_BANK_ACCOUNT,
{
Expand Down
14 changes: 12 additions & 2 deletions src/libs/actions/ReimbursementAccount/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Onyx from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import type CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {ReimbursementAccountForm} from '@src/types/form';
import type {BankAccountSubStep} from '@src/types/onyx/ReimbursementAccount';
import type {ReimbursementAccountSubStep} from '@src/types/onyx/ReimbursementAccount';
import resetNonUSDBankAccount from './resetNonUSDBankAccount';
import resetUSDBankAccount from './resetUSDBankAccount';

Expand All @@ -14,7 +16,7 @@ export {setBankAccountFormValidationErrors, resetReimbursementAccount} from './e
* - CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL to ask them to enter their accountNumber and routingNumber
* - CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID to ask them to login to their bank via Plaid
*/
function setBankAccountSubStep(subStep: BankAccountSubStep | null): Promise<void | void[]> {
function setBankAccountSubStep(subStep: ReimbursementAccountSubStep | null): Promise<void | void[]> {
return Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {achData: {subStep}});
}

Expand Down Expand Up @@ -49,6 +51,13 @@ function cancelResetBankAccount() {
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {shouldShowResetModal: false});
}

/**
* Sets pressed option during connecting reimbursement account
*/
function setReimbursementAccountOptionPressed(optionPressed: ValueOf<typeof CONST.BANK_ACCOUNT.SETUP_TYPE>) {
Onyx.set(ONYXKEYS.REIMBURSEMENT_ACCOUNT_OPTION_PRESSED, optionPressed);
}

export {
resetUSDBankAccount,
resetNonUSDBankAccount,
Expand All @@ -59,4 +68,5 @@ export {
cancelResetBankAccount,
clearReimbursementAccountDraft,
setBankAccountState,
setReimbursementAccountOptionPressed,
};
31 changes: 31 additions & 0 deletions src/pages/ReimbursementAccount/NonUSD/Country/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import CountryFullStep from '@components/SubStepForms/CountryFullStep';

type CountryProps = {
/** Handles back button press */
onBackButtonPress: () => void;

/** Handles submit button press */
onSubmit: () => void;

/** Array of step names */
stepNames: readonly string[];

/** ID of current policy */
policyID: string | undefined;
};

function Country({onBackButtonPress, onSubmit, stepNames, policyID}: CountryProps) {
return (
<CountryFullStep
onBackButtonPress={onBackButtonPress}
onSubmit={onSubmit}
stepNames={stepNames}
policyID={policyID}
/>
);
}

Country.displayName = 'Country';

export default Country;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Agreements from './Agreements';
import BankInfo from './BankInfo/BankInfo';
import BeneficialOwnerInfo from './BeneficialOwnerInfo/BeneficialOwnerInfo';
import BusinessInfo from './BusinessInfo/BusinessInfo';
import Country from './Country/Country';
import Country from './Country';
import Docusign from './Docusign/Docusign';
import Finish from './Finish';
import SignerInfo from './SignerInfo';
Expand Down
54 changes: 30 additions & 24 deletions src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {InputID} from '@src/types/form/ReimbursementAccountForm';
import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
import type {ACHDataReimbursementAccount} from '@src/types/onyx/ReimbursementAccount';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import ConnectedVerifiedBankAccount from './ConnectedVerifiedBankAccount';
Expand Down Expand Up @@ -92,19 +93,24 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
: `${environmentURL}/${ROUTES.WORKSPACE_INITIAL.getRoute(policyIDParam, Navigation.getActiveRoute())}`;

const contactMethodRoute = `${environmentURL}/${ROUTES.SETTINGS_CONTACT_METHODS.getRoute(backTo)}`;
const achData = reimbursementAccount?.achData;
const isPreviousPolicy = policyIDParam === achData?.policyID;
const hasConfirmedUSDCurrency = (reimbursementAccountDraft?.[INPUT_IDS.ADDITIONAL_DATA.COUNTRY] ?? '') !== '' || (achData?.accountNumber ?? '') !== '';

/**
The SetupWithdrawalAccount flow allows us to continue the flow from various points depending on where the
user left off. This view will refer to the achData as the single source of truth to determine which route to
display. We can also specify a specific route to navigate to via route params when the component first
mounts which will set the achData.currentStep after the account data is fetched and overwrite the logical
next step.
We main rely on `achData.currentStep` to determine the step to display in USD flow.
This data is synchronized with the BE to know which step to resume/start from.
Except for the CountryStep which exists purely in the FE.
This function is to decide if we should start from the CountryStep.
*/
const achData = reimbursementAccount?.achData;
const isPreviousPolicy = policyIDParam === achData?.policyID;
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const getInitialCurrentStep = () => {
if (!hasConfirmedUSDCurrency) {
return CONST.BANK_ACCOUNT.STEP.COUNTRY;
}

const currentStep = !isPreviousPolicy ? CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT : (achData?.currentStep ?? CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT);
return achData?.currentStep ?? CONST.BANK_ACCOUNT.STEP.COUNTRY;
};
const currentStep = getInitialCurrentStep();
const [nonUSDBankAccountStep, setNonUSDBankAccountStep] = useState<string | null>(null);
const [USDBankAccountStep, setUSDBankAccountStep] = useState<string | null>(null);

Expand Down Expand Up @@ -245,15 +251,17 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
Navigation.setParams({stepToOpen: getRouteForCurrentStep(currentStep)});
},
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
[isOffline, reimbursementAccount, route, hasACHDataBeenLoaded, shouldShowContinueSetupButton],
[isOffline, reimbursementAccount, hasACHDataBeenLoaded, shouldShowContinueSetupButton, currentStep],
);

const continueUSDVBBASetup = () => {
const continueUSDVBBASetup = useCallback(() => {
// If user comes back to the flow we never want to allow him to go through plaid again
// so we're always showing manual setup with locked numbers he can not change
setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL).then(() => {
setShouldShowContinueSetupButton(false);
setUSDBankAccountStep(currentStep);
});
};
}, [currentStep]);

const continueNonUSDVBBASetup = () => {
const isPastSignerStep = achData?.corpay?.signerFullName && achData?.corpay?.authorizedToBindClientToAgreement === undefined;
Expand Down Expand Up @@ -299,24 +307,21 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
}
};

const goBack = () => {
const subStep = achData?.subStep;
const goBack = useCallback(() => {
const shouldShowOnfido = onfidoToken && !achData?.isOnfidoSetupComplete;

switch (currentStep) {
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
case CONST.BANK_ACCOUNT.STEP.COUNTRY:
if (hasInProgressVBBA()) {
setShouldShowContinueSetupButton(true);
}
if (subStep) {
setUSDBankAccountStep(null);
setBankAccountSubStep(null);
setPlaidEvent(null);
} else {
Navigation.goBack();
}
setUSDBankAccountStep(null);
setBankAccountSubStep(null);
break;
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
setPlaidEvent(null);
goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COUNTRY);
break;

case CONST.BANK_ACCOUNT.STEP.COMPANY:
clearOnfidoToken();
goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
Expand Down Expand Up @@ -352,7 +357,7 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
default:
Navigation.dismissModal();
}
};
}, [achData?.isOnfidoSetupComplete, achData?.state, currentStep, hasInProgressVBBA, isOffline, onfidoToken]);

const isLoading =
(isLoadingApp || !!account?.isLoading || (reimbursementAccount?.isLoading && !reimbursementAccount?.isCreateCorpayBankAccount)) &&
Expand All @@ -361,6 +366,7 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
const shouldShowOfflineLoader = !(
isOffline &&
[
CONST.BANK_ACCOUNT.STEP.COUNTRY,
CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT,
CONST.BANK_ACCOUNT.STEP.COMPANY,
CONST.BANK_ACCOUNT.STEP.REQUESTOR,
Expand Down
Loading
Loading