[Payment due @mkhutornyi] Allow clearing the Default Vendor by re-selecting it (CC/DC export only)#96227
[Payment due @mkhutornyi] Allow clearing the Default Vendor by re-selecting it (CC/DC export only)#96227Beamanator wants to merge 5 commits into
Conversation
Tapping the currently-selected vendor on any accounting integration's Default Vendor selector now clears it. Previously the guarded update call skipped this case, leaving no path to unset the field from the UI. QBO and QBD send CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE; Sage Intacct, Certinia, and NetSuite send an empty string. Fixes Expensify/Expensify#659748
|
@Eskalifer1 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] |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
|
Hi @Beamanator, let me know when this is ready for review, thank you! |
|
Sounds good @Eskalifer1 - actually this requires being added to the |
|
Oh, i hadn't done it before. Feel free to reassign. Thank you! |
|
Thanks for the quick response @Eskalifer1 , and thanks @mkhutornyi for volunteering to take over! |
trjExpensify
left a comment
There was a problem hiding this comment.
Hm, not sure about this. For export with vendor bills, you must have a vendor chosen for export. So I don't know why we'd let you deselect a vendor to have no vendor selected. CC: @heyjennahay
|
minnnnteresting - @trjExpensify i'll tag you in slack here :D https://expensify.slack.com/archives/C03TME82F/p1784118449309309 |
| if (row.value !== nonReimbursableBillDefaultVendor) { | ||
| updateQuickbooksDesktopNonReimbursableBillDefaultVendor(policyID, row.value, nonReimbursableBillDefaultVendor); | ||
| } | ||
| const newValue = row.value === nonReimbursableBillDefaultVendor ? (CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE as string) : row.value; |
There was a problem hiding this comment.
as string cast here looks unnecessary.
|
@mkhutornyi i'm so sorry, i just asked you to review but can you pause reviewing this one for now? Just will we get @trjExpensify 's comment(s) sorted 🙏 [we're discussing in slack] |
Blank default vendor has a defined UX only on the CC/DC export path (falls back to "Credit Card Misc"). For Vendor Bill export, blank falls back to the report submitter and is set by disabling the parent toggle, so re-tapping to clear is out of scope. Per team alignment on https://expensify.slack.com/archives/C03TME82F/p1784118449309309, the PR now covers: - QBO shared page: gated on configKey === 'nonReimbursableCreditCardDefaultVendor' - Sage Intacct: gated on settingName === NON_REIMBURSABLE_CREDIT_CARD_VENDOR Reverts the QBD, NetSuite, and Certinia changes — those integrations only support Vendor Bill export, not CC/DC.
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
|
@MelvinBot review |
|
🤖 Reviewed the diff. The change is clean, minimal, and correctly scoped to the CC/DC export paths. One backend item to confirm before merge, plus a minor consistency nit. ✅ Looks good
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
|
Ok I believe we're good to go here now @mkhutornyi 🙏 (ready for another review) |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safariweb.mov |
|
@mjasikowski 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] |
|
🎯 @mkhutornyi, 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. |

Explanation of Change
On accounting integrations where the non-reimbursable export destination is Credit Card / Debit Card, blank Default Vendor has a defined UX — expenses without a vendor export to "Credit Card Misc". But once a Default Vendor is set on those export paths, there's no way to clear it: tapping the currently-selected row is a silent no-op that just navigates back. This blocks vendor-matching CC beta testers who need to reset workspaces between test scenarios.
This change lets the user re-tap the currently-selected vendor to clear it, but only on the CC/DC export paths:
QuickbooksNonReimbursableVendorSelectPage: gated onconfigKey === 'nonReimbursableCreditCardDefaultVendor'. The Bill entry point of the same shared page keeps its existing behavior.DynamicSageIntacctDefaultVendorPage: gated onsettingName === CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR. The Bill and reimbursable variants keep their existing behavior.Vendor Bill export paths are intentionally out of scope — blank on those integrations means "use the report submitter" and is set by disabling the parent Default Vendor toggle rather than by clearing the vendor from this list. QBD, NetSuite, and Certinia only support Vendor Bill export, so they're not touched.
Xero doesn't have a Default Vendor selector today; it will be added as part of the broader vendor-matching project.
Backend paths verified end-to-end:
'NONE'fornonReimbursableCreditCardDefaultVendorhas an existing frontend precedent:DynamicQuickbooksCompanyCardExpenseAccountPage.tsx#L128-L135already sends theNONEsentinel to clear the bill default vendor.api.php:3361-3367:UpdateSageIntacctNonreimbursableExpensesCreditCardChargeExportDefaultVendorreads$_REQUEST['vendorID'] ?? ''and forwards toPolicyAPI::updateManyPolicyConnectionConfigurations— no validation.PolicyAPI::updateManyPolicyConnectionConfigurationsonly special-casesautoSync.enabled; passes everything else through to Auth — no validation.UpdateManyPolicyConnectionConfigurationsenforces JSON-type consistency between current and new value. This field is typedstringin Onyx and App only ever writes strings (real vendor ID or''), soSTRING → STRINGpasses the check. Persistence is a straightJSONB_PATCH— the empty string is stored as-is.Known limitation — OldDot's Intacct export view clears this field by writing JSON
null, not''. If a workspace previously cleared the vendor from OldDot, the stored value isnulland the NewDot clear (empty string) would fail Auth's type check with400 Current value and new value are using different types. In practice this is rare — OldDot doesn't support vendor matching, so anyone actively using the CC/DC vendor default is already on NewDot — but flagging it as a known edge case.Fixed Issues
$ https://github.com/Expensify/Expensify/issues/659748
PROPOSAL: https://github.com/Expensify/Expensify/issues/659748#issuecomment-4985966633
Tests
QBO — Credit Card export path:
QBO — Vendor Bill export path (regression check, should NOT toggle):
Sage Intacct — Credit Card Charge path:
Sage Intacct — Vendor Bill / Reimbursable paths (regression check, should NOT toggle):
Offline tests
QA Steps
Same as tests - tag me & @heyjennahay to perform these and the rest of the Vendor Matching for CC Expenses flows
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionmainbranch 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