Skip to content

Add a Time sensitive to-do for employees with missing deposit accounts - #96623

Merged
grgia merged 19 commits into
Expensify:mainfrom
software-mansion-labs:feature/home/time-sensitive-card
Aug 10, 2026
Merged

Add a Time sensitive to-do for employees with missing deposit accounts#96623
grgia merged 19 commits into
Expensify:mainfrom
software-mansion-labs:feature/home/time-sensitive-card

Conversation

@sharabai

@sharabai sharabai commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

This PR adds a Time sensitive Home item when an ACH reimbursement is queued because the current payee has no personal deposit account. It uses the queued action's paymentType to exclude Wallet/KYC waits, opens the existing bank-account setup flow, and adds the required route, copy, documentation, and unit coverage.

Fixed Issues

$ #88187
$ #97462
PROPOSAL: #88187 (comment)

Tests

ACH reimbursement waiting for a personal bank account

Preconditions:

  • User A owns or administers a workspace with Payments enabled, a verified business bank account selected as the payment account, and User A selected as the authorized payer.
  • User B is a validated regular member of that workspace and has no personal bank account under Account → Wallet.
  1. As User B, create a small manual expense in the workspace and submit it.
  2. As User A, approve the expense if required and pay it with the workspace's business bank account.
  3. As User B, go directly to Home without opening the expense report.
  4. Verify that Time sensitive shows one item titled Add a bank account to get reimbursed, with Wallet as the subtitle and Add as the CTA.
  5. Hard-refresh Home and verify that the item remains visible and is not duplicated.
  6. Press Add and verify that the personal bank-account setup flow opens.
  7. Add a personal bank account using Plaid sandbox credentials.
  8. Verify that the Add a bank account to get reimbursed item disappears from Home.

Wallet payment exclusion (not manually verified)

Note

I couldn't manually verify this case with the available test setup. The payer has a test Wallet, while an unactivated recipient is treated as a non-test Wallet, and the backend rejects that pairing with error code 666: “Cannot mix test and non-test wallets in a payment.” Therefore, the queued Wallet state can't currently be reached with these test accounts.

Note

@MariaHCD is working on fixing this in this issue. Once that's done, testing should be possible by following these steps: All you would need to do to set up a test pending wallet is just to fill out the additional details form with the test data and then abandon the KYC flow. That will result in a test pending wallet.

Preconditions:

  • User C has an activated non-test Expensify Wallet.
  • User D has not activated their Expensify Wallet and has no personal bank account.
  1. As User C, send or pay money to User D using Pay with Expensify.
  2. As User D, open the affected report.
  3. Verify that the queued-payment message shows Enable wallet.
  4. Go to Home.
  5. Verify that Add a bank account to get reimbursed is not shown for this Wallet/KYC wait.
  • Verify that no errors appear in the JS console

Offline tests

N/A — this change only derives UI from existing Onyx state and opens the existing bank-account setup flow. It adds no API calls, writes, or offline-specific behavior.

QA Steps

Same as tests.

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
time.card.mp4

[!NOTE]
The second recording was captured after fixing the bank-account setup exit navigation. It shows that Continue now closes the flow and returns to Home instead of navigating back to /add-us-bank-account/entry-point.

fix.success.navigation.mp4

@melvin-bot

melvin-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Hey, I noticed you changed src/languages/en.ts in a PR from a fork. For security reasons, translations are not generated automatically for PRs from forks.

If you want to automatically generate translations for other locales, an Expensify employee will have to:

  1. Look at the code and make sure there are no malicious changes.
  2. Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running:

npx ts-node ./scripts/generateTranslations.ts --help

Typically, you'd want to translate only what you changed by running npx ts-node ./scripts/generateTranslations.ts --compare-ref main

@sharabai
sharabai marked this pull request as ready for review July 21, 2026 11:13
@sharabai
sharabai requested review from a team as code owners July 21, 2026 11:14
@melvin-bot
melvin-bot Bot requested review from trjExpensify and removed request for a team July 21, 2026 11:14
@sharabai
sharabai marked this pull request as draft July 21, 2026 11:14
@melvin-bot
melvin-bot Bot requested review from Gonals and removed request for a team July 21, 2026 11:14
@melvin-bot

melvin-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

@Gonals Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

Comment thread src/pages/home/TimeSensitiveSection/hooks/useTimeSensitiveAddBankAccount.ts Outdated
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/CONST/index.ts 94.81% <ø> (ø)
src/components/SettlementButton/index.tsx 87.73% <ø> (-0.05%) ⬇️
src/libs/ReportUtils.ts 86.90% <100.00%> (-0.17%) ⬇️
src/pages/AddPersonalBankAccountPage/index.tsx 72.50% <ø> (+72.50%) ⬆️
...iveSection/hooks/useTimeSensitiveAddBankAccount.ts 100.00% <100.00%> (ø)
src/pages/home/TimeSensitiveSection/index.tsx 75.60% <100.00%> (+0.92%) ⬆️
...home/TimeSensitiveSection/items/AddBankAccount.tsx 100.00% <100.00%> (ø)
...port/actionContents/ReimbursementQueuedContent.tsx 95.00% <100.00%> (ø)
...positAccount/CountrySelectionVerifyAccountPage.tsx 0.00% <ø> (ø)
src/ROUTES.ts 22.82% <0.00%> (-0.03%) ⬇️
... and 3 more
... and 121 files with indirect coverage changes

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89c755aa46

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 89c755aa46

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89c755aa46

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sharabai
sharabai marked this pull request as ready for review July 23, 2026 18:36
@GCyganek

GCyganek commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

I suppose we pass this param to save the background screen
Without this param, we reset the background screen after reloading the page
But probably yes
I suppose it's not a critical issue
Just a bit confusing why we stopped passing backTo on Where's your bank account located screen 😅

Have we been doing that? I'm not convinced that this is regression from changes on this PR, as we just call openPersonalBankAccountSetupView (already implemented before this PR) on Add tap and there are no navigation changes related to this from what I see. Thanks for clarifying this, I can confirm that when I refresh the page on that screen the bg screen is different so this is not ideal, I'm just not sure if we should fix this on this branch and if it wouldn't require migrating screens to dynamic routes to avoid adding new backTo to that screen

@GCyganek

GCyganek commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

How it should look
https://dev.new.expensify.com:8082/settings/wallet/add-bank-account/country/?backTo=%2Fhome
And what we have after validation
https://dev.new.expensify.com:8082/settings/wallet/add-bank-account/:subPage/?%2F%3Aaction=null

Ah yes I see, thank you! will try to fix it

@GCyganek

GCyganek commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@ZhenjaHorbach navigation after account validation should be fixed now, I also replaced all ROUTES.SETTINGS_ADD_BANK_ACCOUNT.route to ROUTES.SETTINGS_ADD_BANK_ACCOUNT.getRoute() to avoid instances where we show /:subPage/?%2F%3Aaction=null url suffix:

Screen.Recording.2026-08-05.at.13.48.33.mov

@ZhenjaHorbach

ZhenjaHorbach commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I suppose we pass this param to save the background screen
Without this param, we reset the background screen after reloading the page
But probably yes
I suppose it's not a critical issue
Just a bit confusing why we stopped passing backTo on Where's your bank account located screen 😅

Have we been doing that? I'm not convinced that this is regression from changes on this PR, as we just call openPersonalBankAccountSetupView (already implemented before this PR) on Add tap and there are no navigation changes related to this from what I see. Thanks for clarifying this, I can confirm that when I refresh the page on that screen the bg screen is different so this is not ideal, I'm just not sure if we should fix this on this branch and if it wouldn't require migrating screens to dynamic routes to avoid adding new backTo to that screen

Yes
Let's skip this
If QA team has any questions
Then we'll fix it 😁

@ZhenjaHorbach

Copy link
Copy Markdown
Contributor

@ZhenjaHorbach navigation after account validation should be fixed now, I also replaced all ROUTES.SETTINGS_ADD_BANK_ACCOUNT.route to ROUTES.SETTINGS_ADD_BANK_ACCOUNT.getRoute() to avoid instances where we show /:subPage/?%2F%3Aaction=null url suffix:

Screen.Recording.2026-08-05.at.13.48.33.mov

And this works well
Thanks for fixing!

@stephanieelliott
stephanieelliott removed their request for review August 10, 2026 07:13
@grgia
grgia merged commit eb639ec into Expensify:main Aug 10, 2026
40 of 42 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🚧 grgia has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/grgia in version: 9.4.52-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 cancelled 🔪

@MelvinBot

Copy link
Copy Markdown
Contributor

Help site review — docs changes required ✅

I reviewed the changes in this PR against the help site (docs/articles). This PR adds a new Time-sensitive to-do — Add a bank account to get reimbursed (subtitle Wallet, CTA Add) — shown when an ACH reimbursement is queued for a payee with no personal deposit account.

Good news: you already documented the feature itself in Expensify-Home-Overview.md by adding this bullet to the "These alerts appear when" list:

  • A reimbursement is waiting for the payee to add a personal deposit account

That line is accurate, so the feature is covered. One correction is still required, though: the sentence directly beneath that list still reads:

Alerts are only shown for active Expensify Cards. Deactivated or closed cards do not trigger time-sensitive alerts.

That blanket claim is now inaccurate — the Time-sensitive section covers non-card alerts (blocked workflows, locked bank accounts, and your new reimbursement/deposit-account alert). The "active card" qualifier only applies to the Expensify Card fraud alert. Adding your new bullet directly above it makes the contradiction plain.

Draft help site PR: #98211 — scopes that one sentence to Expensify Card fraud alerts are only shown for active cards. (one-line change, HelpDot label applied, assigned to you).


@sharabai, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review

@IuliiaHerets

Copy link
Copy Markdown

Hi @sharabai.The QA team is unable to validate Test 2 (Wallet payment exclusion – not manually verified). The test requires a non-test Expensify Wallet / test-pending wallet.

We set up the wallet using the usual Plaid flow, but we’re getting an error when trying to complete Step 1.

Could you please advise how we can set up the required wallet for this test?

96623-Web-2.mp4

cc @JmillsExpensify @grgia @ZhenjaHorbach

@GCyganek

Copy link
Copy Markdown
Contributor

@sharabai is still OOO until thursday and I'm not sure how to do that, but maybe @MariaHCD can help here? I tried to do this test with an unactivated recipient and it returns the same error and I checked response from the backend and it's the same as @sharabai described in the note for this test (error code 666, same description). I also tested with activated account and added bank account via Enable wallet with abandoned state on Verify identity step, then Paying with wallet works, but I'm not sure if this is the same as pending wallet state

Copy link
Copy Markdown
Contributor

Right, or @joekaufmanexpensify might know.

@joekaufmanexpensify

Copy link
Copy Markdown
Contributor

I found this issue about supporting testing wallets in the pending state that was recently completed. I think I pieced together test steps from it. Going to share them to you in slack @IuliiaHerets

@joekaufmanexpensify

Copy link
Copy Markdown
Contributor

Shared here

@IuliiaHerets

Copy link
Copy Markdown

@joekaufmanexpensify After following the steps you shared, the behavior doesn’t match what’s outlined. We can’t send money to User D without completing the Enable Wallet flow.

Since we’re unable to test this PR on our side, could you please verify it internally?

Grabando.1562.mp4

@joekaufmanexpensify

joekaufmanexpensify commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Preconditions:

  • User C has an activated non-test Expensify Wallet.
  • User D has not activated their Expensify Wallet and has no personal bank account.
  1. As User C, send or pay money to User D using Pay with Expensify.
  2. As User D, open the affected report.
  3. Verify that the queued-payment message shows Enable wallet.
  4. Go to Home.
  5. Verify that Add a bank account to get reimbursed is not shown for this Wallet/KYC wait.

I was able to get a test wallet into the pending state. I then processed the payment from an activated test wallet to the pending wallet and confirmed we showed the enable wallet system message and no task on the home page.

It didn't work for me with a non-test activated wallet because we throw an error when a payment is processed between a non-test and test wallet. I think that's actually relevant to the test, though.

2026-08-12_10-27-41 image

@joekaufmanexpensify

Copy link
Copy Markdown
Contributor

Checked off for QA!

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/roryabraham in version: 9.4.52-11 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

HelpDot Apply this label if the issue relates to ExpensifyHelp

Projects

None yet

Development

Successfully merging this pull request may close these issues.