Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
2ce68c7
Add Validation_Failed state
dominictb Aug 6, 2026
2190814
Add NOC code constants
dominictb Aug 6, 2026
94b144b
Add terms
dominictb Aug 6, 2026
5357409
Add lastNocCode to types
dominictb Aug 6, 2026
ea2d771
Add NOC code helper
dominictb Aug 6, 2026
6ba314f
Add support for Validation_Failed connection status
dominictb Aug 6, 2026
f23b343
Update getBankAccountConnectionStatus usage in PaymentMethodList
dominictb Aug 6, 2026
9296371
Update getBankAccountConnectionStatus usage in WorkspaceWorkflowsPage
dominictb Aug 6, 2026
836e974
Update getBankAccountConnectionStatus usage in test
dominictb Aug 6, 2026
b02a655
Fix spellcheck
dominictb Aug 6, 2026
8bf4771
Run generateTranslations script
dominictb Aug 6, 2026
c76f360
Initialize FixBankAccountPage
dominictb Aug 6, 2026
6f3c380
Add type definition for ResendFailedValidationAmounts command
dominictb Aug 6, 2026
73c4d55
Add ResendFailedValidationAmounts command
dominictb Aug 6, 2026
9aa2671
Add translation terms for FixBankAccount page
dominictb Aug 6, 2026
450bf4d
Run generateTranslations script
dominictb Aug 6, 2026
ea4c06a
Update translation style
dominictb Aug 6, 2026
25f3484
Run generateTranslations script
dominictb Aug 6, 2026
ee2b6d1
Show success state
dominictb Aug 6, 2026
9a28b08
Show insufficient funds error
dominictb Aug 6, 2026
bb05812
Show debit blocked error
dominictb Aug 6, 2026
356a6ae
Only show RBR for insufficient funds and debit blocked error
dominictb Aug 6, 2026
7d34fdf
Expose requiresFixHandler
dominictb Aug 6, 2026
1ec0b51
Navigate to FixBankAccountPage on tapping Fix
dominictb Aug 6, 2026
28ac5f4
Navigate to FixBankAccountPage from workspace workflows page
dominictb Aug 6, 2026
e92eae2
Update route entry point
dominictb Aug 6, 2026
7bb4f38
Navigate to FixBankAccountPage from payment flow
dominictb Aug 6, 2026
d869204
Update success text style
dominictb Aug 6, 2026
380b9d4
Remove HTML from insufficientFundsBody
dominictb Aug 6, 2026
98cdc20
Do not use HTML for insufficient funds error
dominictb Aug 6, 2026
54fae1b
Optimistically set data in action
dominictb Aug 6, 2026
a5c3408
Show loading indicator
dominictb Aug 6, 2026
5464c03
Fix lint
dominictb Aug 6, 2026
691d159
Add illustrations
dominictb Aug 7, 2026
4fa0ea7
Replace illustrations in FixBankAccountPage
dominictb Aug 7, 2026
5aa710c
Compress SVG
dominictb Aug 7, 2026
4436708
Add English generic error message
dominictb Aug 7, 2026
d11a2d7
Run generateTranslations script
dominictb Aug 7, 2026
4988ac7
Show generic error message for other NOC codes
dominictb Aug 7, 2026
ee1d8b0
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Aug 11, 2026
bb4299b
Enfore bankAccountID param as string
dominictb Aug 11, 2026
d6a7e67
Add selector for bankAccountList
dominictb Aug 11, 2026
0a81354
Remove displayName from FixBankAccountPage
dominictb Aug 11, 2026
fac8f27
Do not navigate if methodID is undefined
dominictb Aug 11, 2026
9ea10a6
Do not navigate if methodID is undefined
dominictb Aug 11, 2026
261e021
Enfore bankAccountID param as string
dominictb Aug 11, 2026
e5f950d
Add tests for resendFailedValidationAmounts action
dominictb Aug 11, 2026
ecfd884
Add tests for hasInsufficientFundsError and hasDebitBlockedError utils
dominictb Aug 11, 2026
ab64da9
Remove redundant br in translations
dominictb Aug 11, 2026
d128ae5
Render error message above submit button
dominictb Aug 11, 2026
9bb53f2
Fix double back button
dominictb Aug 11, 2026
e012eff
Fix mismatch button paddings
dominictb Aug 11, 2026
f81112c
Fix lint
dominictb Aug 11, 2026
7f7c72d
Fix test
dominictb Aug 12, 2026
7b60721
Fix error message pushes main content
dominictb Aug 12, 2026
ee0f897
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 3, 2026
c7e994d
Reapply test changes
dominictb Sep 3, 2026
8f8acd0
Revert "Remove the unused actionRequired copy"
dominictb Sep 3, 2026
d150eda
Fix typescript
dominictb Sep 3, 2026
3eb6b13
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 3, 2026
46275e5
Revert redundant changes
dominictb Sep 3, 2026
d8f7d4b
Execute fix handler in workspace workflows page
dominictb Sep 3, 2026
b99ee51
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 7, 2026
70beb34
Show RBR on Wallet menu item when having validation failed BA
dominictb Sep 7, 2026
b941bf2
fix: tapping bank account row not open validaiton failed page
dominictb Sep 7, 2026
a665f43
Show RBR not GBR
dominictb Sep 7, 2026
d989dde
Added indicator status constant for validation failed BA
dominictb Sep 7, 2026
eaac7ff
Added indicator status for validation failed BA
dominictb Sep 7, 2026
cdb2a54
Added indicator status message for validation failed BA
dominictb Sep 7, 2026
56d29df
Use accountData from bankAccountList
dominictb Sep 7, 2026
76499a5
Add unit tests for new indicator status
dominictb Sep 7, 2026
adf7936
Apply translation script
dominictb Sep 7, 2026
f5076c9
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 10, 2026
b8c2e54
Fix typecheck
dominictb Sep 10, 2026
02f8f70
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 14, 2026
1fb3044
Treat Validation_Failed as partially setup so all partially setup BBA…
dominictb Sep 17, 2026
6c2c65d
Remove redundant guard from pay button
dominictb Sep 17, 2026
a9a302d
Show partially-setup BBAs in payment methods
dominictb Sep 22, 2026
05f81c8
Drop Validation_Failed handler from SettlementButton
dominictb Sep 22, 2026
e7051b8
Add a shared helper to handle partially-setup BA selection
dominictb Sep 22, 2026
3f6b96e
Rename the helper for consistency
dominictb Sep 22, 2026
6028134
Prepend the handler to primary payment flows
dominictb Sep 22, 2026
2bc4598
Create an Onyx selector for bank account states only
dominictb Sep 22, 2026
0d15822
Prepend the handler to primary payment flows
dominictb Sep 22, 2026
d9af617
Update unit tests
dominictb Sep 22, 2026
34f0fa2
Prepend the handler to primary payment flows
dominictb Sep 22, 2026
b560ca6
Prepend the handler to primary payment flows
dominictb Sep 22, 2026
05a55c3
Add a helper to check if policy has validation failed BA
dominictb Sep 22, 2026
bc9e744
Add the validation failed handler to KYC wall to cover default paymen…
dominictb Sep 22, 2026
0e91384
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 22, 2026
6c94024
Use policy achAccount data when it is fully setup
dominictb Sep 23, 2026
aaf28ac
Add Validation_Failed handler to connect existing BA page
dominictb Sep 23, 2026
51ead29
Whitelist connect existing BA screen
dominictb Sep 23, 2026
ff4cfc2
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 23, 2026
fb016ea
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 23, 2026
02ab7fc
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 27, 2026
a8464f3
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 28, 2026
aacc786
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Sep 29, 2026
2eaaf36
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Oct 1, 2026
a2a9fee
Rely on policy ACH account state
dominictb Oct 1, 2026
eab01fa
Drop unused function
dominictb Oct 1, 2026
98b3345
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Oct 1, 2026
bd1c718
Fix lint
dominictb Oct 1, 2026
a196f47
Success state announcement
dominictb Oct 1, 2026
0ef54d3
Add heading role to text
dominictb Oct 1, 2026
e1f6493
Add accessibility label for the action button
dominictb Oct 1, 2026
61b6904
Read the ACH ID by digit, not whole number
dominictb Oct 1, 2026
6add9c8
Add tests
dominictb Oct 1, 2026
c0246ca
Fix lint
dominictb Oct 2, 2026
ab14623
Fix lint
dominictb Oct 2, 2026
0477011
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Oct 8, 2026
a1dc531
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Oct 9, 2026
b79065c
Matching policy ACH account to bank account list by bankAccountID
dominictb Oct 9, 2026
42ee80b
Tapping the payment method should toggle fix modal as well
dominictb Oct 9, 2026
a73eb0a
Revert bad merge commit changes
dominictb Oct 9, 2026
ac3ebec
Fix inconsistent padding between server error and connection status
dominictb Oct 13, 2026
3e096f6
Merge branch 'main' of github.com:dominictb/App into feat/support-val…
dominictb Oct 14, 2026
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
1 change: 1 addition & 0 deletions assets/images/laptop-with-second-screen-bank.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/scissors-cutting-money.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ const CONST = {
OPEN: 'OPEN',
DELETED: 'DELETED',
LOCKED: 'LOCKED',
VALIDATION_FAILED: 'VALIDATION_FAILED',
},
MAX_LENGTH: {
FULL_SSN: 9,
Expand Down Expand Up @@ -960,6 +961,10 @@ const CONST = {
'resultcode.ssn.issued.prior.to.dob',
],
},
NOC_CODE: {
INSUFFICIENT_FUNDS: ['R01', 'R09'] as string[],
DEBIT_BLOCKED: ['R05', 'R06', 'R07', 'R08', 'R10', 'R11', 'R16', 'R23', 'R29'] as string[],
},
},
CORPAY_DOCUMENT: {
ALLOWED_FILE_TYPES: ['pdf', 'jpg', 'jpeg', 'png'],
Expand Down Expand Up @@ -1139,6 +1144,7 @@ const CONST = {
OPEN: 'OPEN',
DELETED: 'DELETED',
LOCKED: 'LOCKED',
VALIDATION_FAILED: 'VALIDATION_FAILED',
},
},
ENABLE_GLOBAL_REIMBURSEMENTS: {
Expand Down Expand Up @@ -9174,6 +9180,7 @@ const CONST = {
HAS_MERGE_HR_SETUP_NEEDED: 'hasMergeHRSetupNeeded',
HAS_HR_CONNECTION_ERROR: 'hasHRConnectionError',
HAS_APPROVAL_WORKFLOW_NON_MEMBER_APPROVER: 'hasApprovalWorkflowNonMemberApprover',
HAS_VALIDATION_FAILED_BANK_ACCOUNT: 'hasValidationFailedBankAccount',
},

DEBUG: {
Expand Down
14 changes: 14 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,20 @@ const DYNAMIC_ROUTES = {
}),
queryParams: ['bankCountry', 'bankCurrency'],
},
FIX_BANK_ACCOUNT: {
path: 'fix-bank-account/:bankAccountID',
entryScreens: [
SCREENS.SETTINGS.WALLET.ROOT,
SCREENS.WORKSPACE.WORKFLOWS,
SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT,
SCREENS.RIGHT_MODAL.SEARCH_REPORT,
SCREENS.RIGHT_MODAL.EXPENSE_REPORT,
SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT,
SCREENS.REPORT,
SCREENS.SEARCH.ROOT,
],
getRoute: (bankAccountID: string) => `fix-bank-account/${bankAccountID}` as const,
},
BANK_ACCOUNT_VERIFY_ACCOUNT: {
path: 'verify-bank-account',
entryScreens: [SCREENS.REIMBURSEMENT_ACCOUNT],
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const SCREENS = {
EMAIL_ISSUE: 'Settings_Email_Issue',
DYNAMIC_VERIFY_ACCOUNT: 'Dynamic_Verify_Account',
DYNAMIC_ADD_BANK_ACCOUNT_VERIFY_ACCOUNT: 'Dynamic_Add_Bank_Account_Verify_Account',
DYNAMIC_FIX_BANK_ACCOUNT: 'Dynamic_Fix_Bank_Account',
DYNAMIC_EXIT_SURVEY_CONFIRM: 'Dynamic_ExitSurvey_Confirm',
DYNAMIC_EXIT_SURVEY_REASON: 'Dynamic_ExitSurvey_Reason',
DYNAMIC_KEYBOARD_SHORTCUTS: 'Dynamic_Keyboard_Shortcuts',
Expand Down
7 changes: 7 additions & 0 deletions src/components/ConnectionStatusMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ type ConnectionStatusMessageProps = {
statusTone?: 'default' | 'success' | 'danger';
onLinkPress?: ComponentProps<typeof RenderHTML>['onLinkPress'];
shouldIncludeHorizontalPadding?: boolean;

/**
* Accessible name for the action button
*/
actionAccessibilityLabel?: string;
};

function ConnectionStatusMessage({
Expand All @@ -32,6 +37,7 @@ function ConnectionStatusMessage({
statusTone = 'default',
onLinkPress,
shouldIncludeHorizontalPadding = true,
actionAccessibilityLabel,
}: ConnectionStatusMessageProps) {
const icons = useMemoizedLazyExpensifyIcons(['DotIndicator']);
const theme = useTheme();
Expand Down Expand Up @@ -76,6 +82,7 @@ function ConnectionStatusMessage({
style={styles.alignSelfStart}
onPress={onActionPress}
isDisabled={isActionDisabled}
accessibilityLabel={actionAccessibilityLabel}
>
<Button.Text>{actionText}</Button.Text>
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ import {TNodeChildrenRenderer} from 'react-native-render-html';
function BulletItemRenderer({tnode}: {tnode: TNode}) {
const styles = useThemeStyles();
const theme = useTheme();
const ariaLabel = tnode.attributes?.['aria-label'];

return (
<View style={[styles.flexRow, styles.w100]}>
<Text style={{color: theme.text, fontSize: fontScale.text, lineHeight: lineHeightScale.text, paddingHorizontal: 8}}>{CONST.DOT_SEPARATOR}</Text>
<View style={styles.flex1}>
<View
style={styles.flex1}
accessible={!!ariaLabel}
accessibilityLabel={ariaLabel}
>
<TNodeChildrenRenderer tnode={tnode} />
</View>
</View>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Icon/chunks/illustrations.chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import Hand from '@assets/images/hand.svg';
import LaptopWithMembers from '@assets/images/illustration-laptop-members.svg';
import LaptopOnDeskWithCoffeeAndKey from '@assets/images/laptop-on-desk-with-coffee-and-key.svg';
import LaptopWithSecondScreenAndHourglass from '@assets/images/laptop-with-second-screen-and-hourglass.svg';
import LaptopWithSecondScreenBank from '@assets/images/laptop-with-second-screen-bank.svg';
import LaptopWithSecondScreenSync from '@assets/images/laptop-with-second-screen-sync.svg';
import LaptopWithSecondScreenX from '@assets/images/laptop-with-second-screen-x.svg';
// Multifactor Authentication Illustrations
Expand Down Expand Up @@ -103,6 +104,7 @@ import ValidateCode from '@assets/images/product-illustrations/validate-code.svg
import WorkspaceScene from '@assets/images/product-illustrations/workspace-scene.svg';
import ReceiptStack from '@assets/images/receipt-upload.svg';
import RunningTurtle from '@assets/images/running-turtle.svg';
import ScissorsCuttingMoney from '@assets/images/scissors-cutting-money.svg';
import Shutter from '@assets/images/shutter.svg';
// Simple Illustrations - Bucket 3 (Common)
import Puzzle from '@assets/images/simple-illustrations/emptystate__puzzlepieces.svg';
Expand Down Expand Up @@ -278,6 +280,7 @@ const Illustrations = {
Computer,
ExpensifyCardImage,
LaptopWithSecondScreenAndHourglass,
LaptopWithSecondScreenBank,
LaptopWithSecondScreenSync,
LaptopWithSecondScreenX,
LaptopOnDeskWithCoffeeAndKey,
Expand Down Expand Up @@ -347,6 +350,7 @@ const Illustrations = {
ReceiptStack,
RunningTurtle,
Shutter,
ScissorsCuttingMoney,
TravelCVV,
TurtleInShell,

Expand Down
11 changes: 10 additions & 1 deletion src/components/KYCWall/BaseKYCWall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {moveIOUReportToPolicy, moveIOUReportToPolicyAndInviteSubmitter} from '@l
import {doesPolicyHavePartiallySetupBankAccount} from '@libs/BankAccountUtils';
import getClickedTargetLocation from '@libs/getClickedTargetLocation';
import Log from '@libs/Log';
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
import setNavigationActionToMicrotaskQueue from '@libs/Navigation/helpers/setNavigationActionToMicrotaskQueue';
import Navigation from '@libs/Navigation/Navigation';
import {hasExpensifyPaymentMethod} from '@libs/PaymentUtils';
Expand All @@ -27,7 +28,7 @@ import {setKYCWallSource} from '@userActions/Wallet';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES';
import type {Route} from '@src/ROUTES';
import {doesPersonalDetailExist, loginSelector} from '@src/selectors/PersonalDetails';
import {lastWorkspaceNumberSelector, ownerPoliciesSelector} from '@src/selectors/Policy';
Expand Down Expand Up @@ -252,6 +253,14 @@ function KYCWall({
return;
}

const achBankAccountID = policy?.achAccount?.bankAccountID;
const achBankAccountState = policy?.achAccount?.bankAccountID ? bankAccountList?.[policy?.achAccount?.bankAccountID]?.accountData?.state : undefined;
if (achBankAccountID && achBankAccountState === CONST.BANK_ACCOUNT.STATE.VALIDATION_FAILED) {
Log.info('[KYC Wallet] Redirecting to fix bank account: policy bank account failed validation', false, {policyID: policy?.id, achBankAccountID});
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.FIX_BANK_ACCOUNT.getRoute(achBankAccountID.toString())));
return;
}

if (policy?.id !== undefined && doesPolicyHavePartiallySetupBankAccount(bankAccountList, policy.id)) {
Log.info('[KYC Wallet] Redirecting to bank account setup: policy has a partially set up bank account', false, {policyID: policy.id});
navigateToBankAccountRoute({policyID: policy.id});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {search} from '@libs/actions/Search';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import {getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportUtils';
import {isTrackOnboardingChoice} from '@libs/OnboardingUtils';
import {selectPartiallySetupBankAccount} from '@libs/PaymentUtils';
import {hasDynamicExternalWorkflow} from '@libs/PolicyUtils';
import {canIOUBePaid as canIOUBePaidAction, hasHeldExpensesFromTransactions as hasHeldExpensesReportUtils, hasUpdatedTotal, isInvoiceReport as isInvoiceReportUtil} from '@libs/ReportUtils';

Expand Down Expand Up @@ -131,7 +132,17 @@ function PayPrimaryAction({reportID, chatReportID, isDisabled}: PayPrimaryAction
}
if (isDelegateAccessRestricted) {
showDelegateNoAccessModal();
} else if (isAnyTransactionOnHold) {
return;
}

if (
type === CONST.IOU.PAYMENT_TYPE.VBBA &&
selectPartiallySetupBankAccount({state: methodID ? bankAccountList?.[methodID]?.accountData?.state : undefined, methodID, policyID: moneyRequestReport?.policyID})
) {
return;
}

if (isAnyTransactionOnHold) {
openHoldMenu({
requestType: CONST.IOU.REPORT_ACTION_TYPE.PAY,
paymentType: type,
Expand Down
5 changes: 3 additions & 2 deletions src/components/Navigation/DebugTabView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ function getSettingsMessage(status: IndicatorStatus | undefined): TranslationPat
return 'debug.indicatorStatus.completeHrSetup';
case CONST.INDICATOR_STATUS.HAS_HR_CONNECTION_ERROR:
return 'debug.indicatorStatus.theresAProblemWithAnHRConnection';
case CONST.INDICATOR_STATUS.HAS_VALIDATION_FAILED_BANK_ACCOUNT:
return 'debug.indicatorStatus.aBankAccountFailedValidation';
default:
return undefined;
}
Expand Down Expand Up @@ -131,10 +133,9 @@ function getSettingsRoute(status: IndicatorStatus | undefined, reimbursementAcco
case CONST.INDICATOR_STATUS.HAS_SYNC_ERRORS:
return ROUTES.WORKSPACE_ACCOUNTING.getRoute(indicatorPolicyID);
case CONST.INDICATOR_STATUS.HAS_USER_WALLET_ERRORS:
return ROUTES.SETTINGS_WALLET;
case CONST.INDICATOR_STATUS.HAS_WALLET_TERMS_ERRORS:
return ROUTES.SETTINGS_WALLET;
case CONST.INDICATOR_STATUS.HAS_LOCKED_BANK_ACCOUNT:
case CONST.INDICATOR_STATUS.HAS_VALIDATION_FAILED_BANK_ACCOUNT:
return ROUTES.SETTINGS_WALLET;
case CONST.INDICATOR_STATUS.HAS_MERGE_HR_SETUP_NEEDED:
case CONST.INDICATOR_STATUS.HAS_HR_CONNECTION_ERROR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import usePolicy from '@hooks/usePolicy';
import {generateDefaultWorkspaceName} from '@libs/actions/Policy/Policy';
import {getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportUtils';
import {isTrackOnboardingChoice} from '@libs/OnboardingUtils';
import {selectPartiallySetupBankAccount} from '@libs/PaymentUtils';
import {hasDynamicExternalWorkflow} from '@libs/PolicyUtils';
import {getReportOrDraftReport, hasHeldExpensesFromTransactions as hasHeldExpensesReportUtils, hasUpdatedTotal, isInvoiceReport as isInvoiceReportUtils} from '@libs/ReportUtils';

Expand All @@ -26,6 +27,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';

import {bankAccountStatesSelector} from '@selectors/BankAccount';
import {hasSeenTourSelector} from '@selectors/Onboarding';
import React from 'react';

Expand Down Expand Up @@ -61,6 +63,7 @@ function PayActionButton() {
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
const [rules] = useOnyx(ONYXKEYS.COLLECTION.RULE);
const [bankAccountStates] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST, {selector: bankAccountStatesSelector});

const isTrackIntentUser = isTrackOnboardingChoice(introSelected?.choice);

Expand All @@ -79,7 +82,14 @@ function PayActionButton() {
}
if (isDelegateAccessRestricted) {
showDelegateNoAccessModal();
} else if (hasHeldExpensesReportUtils(transactions)) {
return;
}

if (type === CONST.IOU.PAYMENT_TYPE.VBBA && selectPartiallySetupBankAccount({state: methodID ? bankAccountStates?.[methodID] : undefined, methodID, policyID: policy?.id})) {
return;
}

if (hasHeldExpensesReportUtils(transactions)) {
onHoldMenuOpen(type, shouldShowPayButton, methodID);
} else if (chatReport && iouReport) {
const currentChatReport = getReportOrDraftReport(chatReportID) ?? chatReport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {payInvoice, payMoneyRequest} from '@libs/actions/IOU/PayMoneyRequest';
import {getChatReportWithFallback, getSearchPayOnyxData} from '@libs/actions/Search';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import Log from '@libs/Log';
import {selectPartiallySetupBankAccount} from '@libs/PaymentUtils';
import {canIOUBePaid, getReimbursableTotal, isArchivedReport, isIndividualInvoiceRoom, isInvoiceReport} from '@libs/ReportUtils';

import CONST from '@src/CONST';
Expand Down Expand Up @@ -111,6 +112,10 @@ function PayActionCell({isLoading, policyID, reportID, hash, amount, shouldDisab
return;
}

if (type === CONST.IOU.PAYMENT_TYPE.VBBA && selectPartiallySetupBankAccount({state: methodID ? bankAccountList?.[methodID]?.accountData?.state : undefined, methodID, policyID})) {
return;
}

const additionalOnyxData = getSearchPayOnyxData(hash, reportID);

if (isInvoiceReport(iouReport)) {
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useAccountIndicatorChecks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {hasPaymentMethodError} from '@libs/actions/PaymentMethods';
import {hasPartiallySetupBankAccount, hasPersonalBankAccountMissingInfo} from '@libs/BankAccountUtils';
import {hasPartiallySetupBankAccount, hasPersonalBankAccountMissingInfo, hasValidationFailedBankAccount} from '@libs/BankAccountUtils';
import {hasCardPendingDigitalWalletApproval, hasPendingExpensifyCardAction} from '@libs/CardUtils';
import {hasSubscriptionGreenDotInfo, hasSubscriptionRedDotError} from '@libs/SubscriptionUtils';
import {expensifyLoginsSelector, hasDeviceManagementError, hasLoginListError, hasLoginListInfo} from '@libs/UserUtils';
Expand Down Expand Up @@ -68,6 +68,7 @@ function useAccountIndicatorChecks(): AccountIndicatorChecksResult {
[CONST.INDICATOR_STATUS.HAS_EMPLOYEE_CARD_FEED_ERRORS]: !isPolicyAdmin ? hasCompanyCardFeedErrors : false,
[CONST.INDICATOR_STATUS.HAS_LOCKED_BANK_ACCOUNT]: Object.values(bankAccountList ?? {}).some((bankAccount) => bankAccount?.accountData?.state === CONST.BANK_ACCOUNT.STATE.LOCKED),
[CONST.INDICATOR_STATUS.HAS_DEVICE_MANAGEMENT_ERROR]: hasDeviceManagementErrorValue,
[CONST.INDICATOR_STATUS.HAS_VALIDATION_FAILED_BANK_ACCOUNT]: hasValidationFailedBankAccount(bankAccountList),
};

const infoChecks: Partial<Record<IndicatorStatus, boolean>> = {
Expand Down
15 changes: 15 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ const translations: TranslationDeepObject<typeof en> = {
copyToClipboard: 'In Zwischenablage kopieren',
thisIsTakingLongerThanExpected: 'Das dauert länger als erwartet ...',
domains: 'Domains',
actionRequired: 'Aktion erforderlich',
duplicate: 'Duplizieren',
duplicated: 'Dupliziert',
duplicateExpense: 'Doppelte Ausgabe',
Expand Down Expand Up @@ -2824,6 +2825,19 @@ const translations: TranslationDeepObject<typeof en> = {
confirmTestTransactions: 'Bitte bestätigen Sie Testtransaktionen',
accountRequiresAttention: 'Dieses Konto erfordert Ihre Aufmerksamkeit',
unlock: 'Entsperren',
debitBlocked: 'Ihre Bank hat Testtransaktionen auf dieses Konto blockiert',
insufficientFunds: 'Testtransaktionen sind aufgrund unzureichender Deckung fehlgeschlagen',
validationFailedFallback: 'Ihre Bank hat Testtransaktionen auf dieses Konto blockiert. <concierge-link>Kontaktieren Sie Concierge</concierge-link>',
},
fixBankAccount: {
title: 'Bankkonto beheben',
debitBlockedBody:
'Ihre Bank hat die Testtransaktionen zu diesem Konto blockiert.<br/><br/>Bitte lassen Sie die ACH-IDs von Expensify auf die Whitelist setzen:<bullet-list><bullet-item>1270239450</bullet-item><bullet-item>2270239450</bullet-item><bullet-item>4270239450</bullet-item></bullet-list>Senden Sie anschließend die Testtransaktionen unten erneut.',
insufficientFundsBody: 'Testtransaktionen sind aufgrund unzureichender Kontodeckung fehlgeschlagen. Sobald wieder Geld verfügbar ist, verwenden Sie die Schaltfläche unten.',
resendButton: 'Transaktionen erneut senden',
successTitle: 'Transaktionen gesendet!',
successBody: 'Prüfen Sie Ihr Bankkonto in den nächsten 1–2 Werktagen.',
successButton: 'Verstanden',
},
},
addCardToDigitalWallet: {
Expand Down Expand Up @@ -11667,6 +11681,7 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc
aBankAccountIsLocked: 'Ein Bankkonto ist gesperrt',
completeHrSetup: 'HR-Einrichtung abschließen',
theresAProblemWithAnHRConnection: 'Es gibt ein Problem mit einer HR-Verbindung',
aBankAccountFailedValidation: 'Ein Bankkonto hat die Validierung nicht bestanden',
},
},
emptySearchView: {
Expand Down
Loading
Loading