fix: pass workspace policyID when exporting with account-level custom templates#92131
Conversation
… templates Account-level export templates have policyID undefined by design, but the backend needs a workspace policy ID to resolve GL codes from category/tag data. Fall back to the report's policyID in useExportActions and compute an effective export policy from the query/selection context in useSearchBulkActions.
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.
|
|
@ShridharGoel 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] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c935ee82f3
ℹ️ 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".
When a selection mixes a workspace expense with policy-less (personal/ unreported) expenses, selectedPolicyIDs.filter(Boolean) collapses to a single ID and the fallback wrongly sent that workspace as the export policyID, resolving GL codes against the wrong scope. Require every selected transaction to have a policyID before applying the fallback.
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-06-05.at.6.00.27.PM.movScreen.Recording.2026-06-05.at.5.58.59.PM.mov |
@aswin-s Are we sure about this? Was this mentioned somewhere? |
@ShridharGoel Each workspace owns its own categories/tags, and the GL code lives on those category/tag definitions inside that workspace's policy. QueueExportSearchWithTemplate accepts only a single policyID (ExportSearchWithTemplateParams.ts:9), so for multi-workspace selections we deliberately send undefined rather than guess one workspace. Picking any single ID would resolve GL codes against the wrong scope. That's why I made the assumption above. |
|
@aswin-s Can you merge main here so that the failing test gets fixed? |
@ShridharGoel Done. |
|
🚧 @madmax330 has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/madmax330 in version: 9.4.1-0 🚀
Bundle Size Analysis (Sentry): |
|
🤖 Help site review: no documentation changes required. This PR is a backend-only bug fix. It changes which There is no user-facing change to document:
The relevant articles remain accurate as-is:
Because no help site changes are needed, I did not create a draft docs PR. If you'd like a troubleshooting/FAQ note added anyway (e.g., "GL codes appear blank in custom template exports"), let me know with @aswin-s — please confirm you agree no help site updates are needed here. If you'd prefer a docs PR after all, reply and I'll create it. |
|
Deploy Blocker #93088 was identified to be related to this PR. |
|
@madmax330 This has been working fine when we had tested. @jponikarchuk Can you test on the adhoc build once? |
|
🚀 Deployed to production by https://github.com/Julesssss in version: 9.4.1-6 🚀
|
Explanation of Change
Account-level export templates have
policyID: undefinedby design (returned bygetExportTemplates). Both export paths — the single-report path inuseExportActions.beginExportWithTemplateand the bulk path inuseSearchBulkActions.beginExportWithTemplate— were forwarding thatundefineddirectly toqueueExportSearchWithTemplate. The backendQueueExportSearchWithTemplatecommand needs a workspace policy ID to resolve GL codes from policy category/tag data, so it returned blank GL code columns.Fix:
src/hooks/useExportActions.ts: Fall back tomoneyRequestReport.policyIDwhen the template has nopolicyID:policyID: policyID ?? moneyRequestReport.policyIDsrc/hooks/useSearchBulkActions.ts: Compute an effective export policy ID from the query/selection context before callingqueueExportSearchWithTemplate, so account-level templates still resolve GL codes when the selected expenses belong to a single workspace. When the selection spans multiple workspaces,policyIDis intentionally left undefined to avoid resolving GL codes against the wrong workspace.Fixed Issues
$ #89388
PROPOSAL: #89388 (comment)
Tests
Preconditions:
{expense:category:glcode}or{expense:tag:glcode}.Bulk export path (
useSearchBulkActions):Single-report export path (
useExportActions):4. Open an expense report on a workspace with GL codes, use the report header menu → Export → choose the account-level custom template
5. Verify the exported file contains the correct GL codes
Verification at the network layer (optional but definitive):
6. With DevTools Network tab open, trigger an export and inspect the
QueueExportSearchWithTemplaterequest body. With this fix on a single-workspace selection,policyIDis present and matches the workspace ID. With a multi-workspace selection,policyIDis absent (intentional).Offline tests
QA Steps
Preconditions (same as Tests):
{expense:category:glcode}or{expense:tag:glcode}Bulk export path:
Single-report path:
4. Open an expense report on the same workspace, use the report header menu → Export → choose the account-level template
5. Verify the exported file contains the correct GL codes
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
CSV files can be verified on desktop only
Android: mWeb Chrome
CSV files can be verified on desktop only
iOS: Native
CSV files can be verified on desktop only
iOS: mWeb Safari
CSV files can be verified on desktop onlyMacOS: Chrome / Safari
Screen.Recording.2026-06-02.at.8.31.56.AM.mp4