Conversation
Adds the UpdateXeroFxExpenseAccount command and the connection types for the account the cost is charged to and the expense accounts to pick from.
Lets an admin pick the Xero expense account the company paid currency conversion cost is posted to.
Only renders for workspaces on the global reimbursements and FX betas.
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
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 bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@mananjadhav 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] |
|
Got this assigned today. Will pick this up tomorrow first thing. |
trjExpensify
left a comment
There was a problem hiding this comment.
The list comes from a new expenseAccounts collection on the Xero connection data, holding profit and loss accounts only. The bank account list Xero ships today would park the cost on the balance sheet where it never reaches the P&L.
Out of curiosity, why do we need a new collection to limit this to expenseAccounts? For the list of chartOfAccounts that we show as categories imported Xero, those accounts have to have "Show in expense claims" checked on the account on the Xero side to show up in Expensify as categories - doesn't that achieve the same thing?
The row and the selector are both gated on the globalReimbursements and globalReimbursementFX betas, and the selector is also blocked unless reimbursed report sync is on, since that is the only path that pays a Xero bill and therefore the only path that posts the cost.
I understand the second beta, as that's this feature in development. What's with the globalReimbursements beta though. Isn't global reimbursement a feature available to everyone? 🤔
Outside of the world of beta lingo, is this feature in the accounting settings gated on a workspace with a bank account configured for global reimbursement?
CC: @heyjennahay for vis too.
Two issues with reusing the categories list:
The new expenseAccounts list filters on Xero's ClassType instead, which is the broader P&L grouping that correctly includes Direct Costs and Overheads and excludes Revenue.
this still exists on backend list of betas, and we only allow USD and AUD currency to bypass the beta
No, just the two account-level betas plus "Sync reimbursed reports" being on, so without a cross-border bank account would still see the row, it just would never end up posting anything since no FX fee would ever occur. Should we hide it in this scenario? |
Why do we want a revenue account to book an employee's expense to?
The
I don't think this accounting configuration should show on a workspace that is not even configured to do cross-border reimbursements, no. I think it will just confuse them. Curious to hear what @heyjennahay thinks about that too. |
we dont thats why we cant reuse the categories list which has revenue accounts and this new list filters those out, so only real expense-type accounts (including Direct Costs and Overheads, which the categories list can also miss) show up as valid places to book the cost
okay good to know, then i think it no-op I'll make the change to remove it from here and later in some other PR from other code |
It's released to everyone in Betaify, so it no longer restricts anything and shouldn't gate new code.
Let me rephrase. Why would an expense, created by an employee and categorised, be okay to book to a revenue account - but is so egregious to show here to the point where we created a totally new coding import grouping for the list. Basically on the one hand you're saying it's not okay to show revenue accounts in this selector because you shouldn't be able to book expenses to that account type, but on the other you're saying revenue accounts appear in the categories list for employees to book expenses to. To me, it feels like there might be an opportunity to align the default lists used for the two instead of maintaining two separate. I'm OOO now until next Tuesday, but I've asked Jenna to have eyes on this (if she hasn't already). |
Yeah agree, although here it's combines with the FX beta, so it doesn't matter. |
|
Sorry, I think I muddled this. Let me start over. What this PR adds: one setting, the Xero expense account we post the company-paid conversion cost to. When the company covers the conversion its bank is debited more than the employee receives, and we post that difference to Xero as a spend money transaction. That line has to land on an expense account. Why the lists we already have don't fit:
It is not a new import. We already fetch every Xero account in one call and discard most of them. This is a second filter over the same response on Let me know if I have misunderstood your question or got any of this wrong. |
|
Reviewing and waiting for this product discussion ^ |
|
I could not review this diff, so I did not approve the workflow runs. An Expensify employee will review it and approve them manually. |
|
Yes. I am reviewing this again. |
|
I totally missed asking one question.
|
|
@ishpaul777 Last few questions, rest I've started with the checklist. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppandroid-xero-fx-fee.movAndroid: mWeb Chromemweb-chrome-xero-fx-fee.moviOS: HybridAppiOS: mWeb Safarimweb-safari-xero-fx-fee.movMacOS: Chrome / Safarixero-fx-fee-account-picker.movxero-fx-disabled.mov |
|
@trjExpensify @ishpaul777 Two quick questions:
|
mananjadhav
left a comment
There was a problem hiding this comment.
LGTM, ask 2 questions on the behavior but can be follow up.
|
🎯 @mananjadhav, thanks for reviewing and testing this PR! 🎉 A payment issue will be created for your review once this PR is deployed to production. If payment is not needed (e.g., regression PR review fix etc), react with 👎 to this comment to prevent the payment issue from being created. |
|
I could not review this diff, so I did not approve the workflow runs. An Expensify employee will review it and approve them manually. |
fixed this one
i will follow up on this if we want to do this 👍 |
|
🚧 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.78-0 🚀
|
|
Yes — help site changes are required. Draft PR: #101137 The Xero currency conversion fee account row this PR adds isn't documented anywhere in What the docs PR changes:
How the copy was verified
I skipped the Currency conversion fees setting under Workflows > Payments — it's also undocumented, but it predates this PR, which only renamed the hook it uses. @ishpaul777, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR view run · no recording available |
|
Deploy Blocker #101166 was identified to be related to this PR. |
|
This PR failing because of the issue #101166 |
|
🚀 Deployed to production by https://github.com/luacmartins in version: 9.4.78-3 🚀
Bundle Size Analysis (Sentry): |
|
🤖 Payment issue created: #101258 |


Explanation of Change
When a company covers the currency conversion cost on a cross-border reimbursement, its bank is debited more than the employee receives. We post that extra cost to Xero as a spend money transaction, and it needs an expense account to book it to. This adds the picker that nominates it, on the Xero advanced page next to the existing bill payment and invoice collections rows.
The list comes from a new
expenseAccountscollection on the Xero connection data, holding profit and loss accounts only. The bank account list Xero ships today would park the cost on the balance sheet where it never reaches the P&L.The row and the selector are both gated on the
globalReimbursementFXbeta and on the workspace reimbursing through Expensify, since that is the only setup where this cost arises. That condition lives inuseCanConfigureCurrencyConversionFeesso every surface exposing these settings agrees on it. The row also sits inside the reimbursed report sync accordion, because paying a Xero bill is what posts the cost.Fixed Issues
$ https://github.com/Expensify/Expensify/issues/672453
PROPOSAL: N/A, internal
Tests
Automated coverage:
tests/unit/PolicyUtilsTest.tsfor the account list mapping,tests/actions/connections/Xero.test.tsfor the optimistic write, the failure rollback, and the missing policy ID case.Manual:
Offline tests
QA Steps
Same as tests. Requires a Xero connected workspace on the
globalReimbursementFXbeta that reimburses through Expensify.PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, 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.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
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2026-08-23.at.4.06.20.PM.mov