Repository navigation
[Due for payment 2026-09-30] [$250] Report - Supplier Address & VAT Number report fields are shown in settings but not shown in the report #72584
Description
Activity
- addedDailyKSv2KSv2BugSomething is broken. Auto assigns a BugZero manager.Something is broken. Auto assigns a BugZero manager.
on Oct 14, 2025 Triggered auto assignment to @abekkala (
Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.🚨 Edited by proposal-police: This proposal was edited at 2025-10-23 16:58:38 UTC.
Proposal
Please re-state the problem that we are trying to solve in this issue.
Workspace admins see supplier address, VAT, and any other invoice-only fields under the Report fields section. Those options should appear under Invoices instead, and new invoice-only custom fields must stay out of the report configuration page.
What is the root cause of that problem?
The report settings screen reads every policy field whose id is not
text_title. It never checks the field target, so invoice-targeted fields are mixed in with actual report fields.
App/src/pages/workspace/reports/WorkspaceReportsPage.tsx
Lines 70 to 105 in 582e7c5
const connectedIntegration = getConnectedIntegration(policy) ?? connectionSyncProgress?.connectionName; const isConnectionVerified = connectedIntegration && !isConnectionUnverified(policy, connectedIntegration); const currentConnectionName = getCurrentConnectionName(policy); const hasAccountingConnections = hasAccountingConnectionsPolicyUtils(policy); const filteredPolicyFieldList = useMemo(() => { if (!policy?.fieldList) { return {}; } // eslint-disable-next-line @typescript-eslint/no-unused-vars return Object.fromEntries(Object.entries(policy.fieldList).filter(([_, value]) => value.fieldID !== 'text_title')); }, [policy]); const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const illustrations = useMemoizedLazyIllustrations(['ReportReceipt'] as const); const onDisabledOrganizeSwitchPress = useCallback(() => { if (!hasAccountingConnections) { return; } setIsOrganizeWarningModalOpen(true); }, [hasAccountingConnections]); const fetchReportFields = useCallback(() => { openPolicyReportFieldsPage(policyID); }, [policyID]); const {isOffline} = useNetwork({onReconnect: fetchReportFields}); useEffect(() => { fetchReportFields(); }, [fetchReportFields]); const reportFieldsSections = useMemo(() => { if (!policy) { return []; } What changes do you think we should make in order to solve the problem?
- Update the report settings filter so it ignores invoice-targeted fields (or we can just check for equality of target).
// WorkspaceReportsPage.tsx return Object.fromEntries( Object.entries(policy.fieldList).filter( ([, value]) => value.fieldID !== 'text_title' && value.target !== CONST.REPORT_FIELD_TARGETS.INVOICE, ), );
- Extend the create-field flow so the caller passes the desired target, and have the form give that out to the optimistic update and the report merge logic.
// ReportField.ts type CreateReportFieldParams = Pick<WorkspaceReportFieldForm, 'name' | 'type' | 'initialValue'> & { ... policyReportIDs: Array<string | undefined> | undefined; target?: PolicyReportField['target']; ... }; function createReportField({... , policyReportIDs, target = CONST.REPORT_FIELD_TARGETS.EXPENSE, policy}: CreateReportFieldParams) { ... const optimisticReportFieldDataForPolicy = { ... target, ... }; const optimisticData = [ { ... }, ...(policyReportIDs ?? []).map((reportID) => ({ ... })), ];
- Allow the create-field route to carry an optional
targetquery param, and pass it through the form so invoice fields only merge into invoice reports.
// ROUTES.ts WORKSPACE_CREATE_REPORT_FIELD: { ... getRoute: (policyID, target) => target ? `${baseRoute}?target=${encodeURIComponent(target)}` : baseRoute, },
// CreateReportFieldsPage.tsx const fieldTarget = useMemo(() => ( target && Object.values(CONST.REPORT_FIELD_TARGETS).includes(target) ? target : CONST.REPORT_FIELD_TARGETS.EXPENSE ), [target]); const policyReportIDsSelector = useCallback( (reports) => Object.values(reports ?? {}) .filter((report) => report?.policyID === policyID && report.type === reportTypeForTarget) .map((report) => report?.reportID), [policyID, reportTypeForTarget], );
- Add a new Invoice fields section under the invoices workspace tab that mirrors the existing report fields UI but only surfaces invoice-targeted data. The menu loads policy fields, lets admins navigate into field settings, and links the add button to the same form but tagged with the invoice target.
// WorkspaceInvoiceFieldsSection.tsx const invoiceFields = useMemo(() => Object.values(policy?.fieldList ?? {}) .filter((field) => field.target === CONST.REPORT_FIELD_TARGETS.INVOICE) .sort((a, b) => localeCompare(a.name, b.name)) .map((field) => ({ text: field.name, keyForList: String(field.fieldID), ... })), [localeCompare, policy?.fieldList, translate]); <MenuItem onPress={() => Navigation.navigate( ROUTES.WORKSPACE_CREATE_REPORT_FIELD.getRoute(policyID, CONST.REPORT_FIELD_TARGETS.INVOICE), )} title={translate('workspace.reportFields.addField')} icon={Plus} ... />
- Add new translation keys for invoice fields so the UI copy matches the design (invoice switch label, subtitles, disable modal text).
// en.ts workspace: { common: { invoiceFields: 'Invoice fields', }, invoiceFields: { subtitle: "Invoice fields can be helpful when you'd like to include extra information.", ... }, },
Note: We'll need to either add a new endpoint for invoice fields, or within the same endpoint we can have a new query param/identifier in request body to tell the backend that the enabling is being done for reports or invoices (since it can happen that one of these might be enabled and the other might not be).
Screen.Recording.2025-10-23.at.10.55.17.PM.mov
- addedExternalAdded to denote the issue can be worked on by a contributorAdded to denote the issue can be worked on by a contributor
on Oct 17, 2025 - changed the title
[-]Report - Supplier Address & VAT Number report fields are shown in settings but not shown in the report[/-][+][$250] Report - Supplier Address & VAT Number report fields are shown in settings but not shown in the report[/+]on Oct 17, 2025 Job added to Upwork: https://www.upwork.com/jobs/~021979200514033151425
- addedHelp WantedApply this label when an issue is open to proposals by contributorsApply this label when an issue is open to proposals by contributors
on Oct 17, 2025 Triggered auto assignment to Contributor-plus team member for initial proposal review - @rojiphil (
External)@rojiphil we did already receive a proposal for this one. Can you give it a look? thanks!
@rojiphil when you have a moment can you please review the two proposals? Thanks!
Reacted by Roji Philip188 remaining items
Load more actions- changed the title
[-][$250] Report - Supplier Address & VAT Number report fields are shown in settings but not shown in the report[/-][+][Due for payment 2026-09-30] [$250] Report - Supplier Address & VAT Number report fields are shown in settings but not shown in the report[/+]on Sep 30, 2026 Triggered auto assignment to @mallenexpensify (
Awaiting Payment)@rojiphil this issue mentions a deploy blocker or a regression. Before the payment date, post one of the three options in step 20 of the C+ doc: it was a regression, it was not, or you did not review the offending PR. If you don't post, the default is to reduce payment.
#72584 was posted for a report-field display bug. Product redefined it into a new Invoice Fields feature, and every follow-up is either that new surface or a narrow path inside it. None of them is a regression of existing behavior. I propose to raise the compensation to $1,000 as that looks reasonable. The details of the work are mentioned below.
@mollfpr @ShridharGoel What do you think?
cc @mallenexpensifyWhat the job became
The report was: on an EUR workspace, Supplier Address and VAT Number appear under Reports settings and do not appear on an expense report. Product then said these are default invoice fields. They should leave the Reports page, and a separate Invoice Fields section should live under Invoices, with its own toggle and its own fields.
That is the work that was reviewed: a new backend command family, two App implementations (#73887, reverted the same day, then #93317, about 87 files), and report rendering, the enable flag, and workspace duplicate/copy all learning a second field target.
Follow-ups
Feature implementation means the case exists only because the job grew into Invoice Fields. Edge case means a narrow or cosmetic path of that feature. Regression would mean an existing production flow broke for workspaces that do not use the new feature. Nothing below is in that last group.
Reverted first ship (#73887)
Issue Reasoning Class #93224 The invoice receiver does not see the field because visibility now requires areInvoiceFieldsEnabled, which the receiver does not have. Receiver visibility did not exist before this feature.Feature implementation #93227 Reply-in-thread on an invoice field edit shows "x owes amount" because the thread header treats any thread under an invoice as the invoice itself. Edge case #93232 Deleting an expense report field also deletes the invoice field. Both targets share fieldList, and the delete payload replaces the whole list. The loss only happens once invoice fields exist in that list.Feature implementation #93233 An offline edit never shows. Invoice field values are read from report name-value pairs and the optimistic write only updates report.fieldList.Edge case #93235 The initial-value page shows an empty padded block because the list selector is given a blank subtitle and the modal still renders that container. Edge case #93240 After a workspace delete, the field vanishes from existing invoices. Expense fields stay on the report and can be removed manually. That parity was not part of the reported bug. Feature implementation #93241 Duplicating a workspace does not copy areInvoiceFieldsEnabledor the invoice fields. Duplicate support was extra surface on the new feature.Feature implementation These seven were closed when the feature was reverted. They never stayed in production.
Ship that reached production (#93317)
Issue Reasoning Class #100756 Creating a report field with the same name removes the invoice field. The feature allows the same name on each target, but both still use one name-derived fieldIDin a sharedfieldList. A workspace with no invoice fields still creates report fields as before. Applause recorded it as a new feature that does not exist in production.Feature implementation #100772 Copy settings omits the "1 invoice fields" count that the duplicate screen already shows. Display-only gap on an adjacent screen. Feature implementation #100790 A paid invoice keeps the LHN fix badge when a field is empty. The settled-report guard was written for expense reports only. Edge case #100878 Invoice fields stay enabled after a downgrade to Collect. Called a very specific edge case on the issue. Edge case #100879 Copy settings hides the invoice row when fields are enabled and none have been added. Called an edge case and left unblocked. Edge case #100876 The duplicate-name error says an invoice field already exists when the clash is with a report field. Wrong string from the fix PR #100850, and it was left as a follow-up. Edge case #100756, #100772, and #100790 were fixed in #100850. #100878, #100879, and #100876 were fixed in #101470. #101799 is an Android expense-report scroll bug from a different PR, #100735.
Reacted by Shridhar GoelAgreed, $1000 sounds fair here. The scope really did balloon from a display bug into a full feature once product redefined it, and the breakdown above matches what I saw reviewing this.
One small correction though: for the second implementation's follow-ups, only 3 of the 6 (#100878, #100879, #100876, fixed in #101470) were actually fixed by @ShridharGoel. The other 3 (#100756, #100772, #100790) I fixed myself in #100850 since it needed a same-day CP. Doesn't change my take on the amount, just want the record to be accurate.
Reacted by Shridhar GoelReacted by Roji Philip@mallenexpensify No BE hours were used for the FE work here. This was started before joining the BE team.
Payment Summary
Contributor: @ShridharGoel due $1000 via NewDot
Contributor+: @rojiphil due $1000 via NewDot@ShridharGoel plz complete the Contributor+ checklist and tag me in a post once you have. Thx
@rojiphil was the reviewer on this, so I think he would fill the checklist.
Reacted by Matt AllenUpdated payment summary to inc. proper reviewer
BugZero Checklist:
-
[Contributor] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to comment: No offending PR as this is a new feature.
-
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion: Not Required. The existing checklist is good enough to capture such issues.
-
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal Template -
[BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.
Link to issue: https://github.com/Expensify/Expensify/issues/688462
Regression Test Proposal
Precondition:
Test:
Do we agree 👍 or 👎
Test 1
- Go to workspace settings.
- Turn on invoices.
- Go to the Invoices tab.
- Verify the Invoice fields section is visible.
- Add a new field.
- Edit the added field.
- Create an invoice and verify the invoice fields are visible.
Test 2
- Enable Invoices, enable Invoice fields, and create a field.
- Workspaces tab → 3-dot menu → Duplicate workspace → Next → Continue.
- Open the duplicated workspace → Invoices.
- Verify Invoice fields are enabled.
Test 3
- Invoices → enable Invoice fields → add a text field.
- Reports → enable Report fields → add a text field → delete it.
- Return to Invoices.
- Verify the invoice field is still there.
- The Offline tests section on both pulls was left empty.
Test 4
- Sign in to two accounts.
- On account B, enable invoices and enter invoice details.
- Send an invoice to account A.
- Enable Invoice fields and add a text field with no initial value.
- Confirm the LHN shows a Fix badge.
- On account A, pay the invoice.
- On account B, open the paid invoice and recheck the LHN.
- Verify the Fix badge is not shown for the paid invoice.
Test 5
- Create workspaces A and B. On A, enable invoices, enter company name and website, and create one invoice field.
- Duplicate workspace A and confirm the Invoices row shows "1 invoice fields".
- Copy settings from A to B.
- Verify the Invoices row shows "1 invoice fields".
Test 6
- Enable Invoice fields and create a text field.
- Enable Report fields and try to create a text field with the same name.
- Verify the name is rejected.
Test 7
- Create a report field named PO Number.
- Try to create an invoice field named PO Number.
- Verify the error is "A report field with this name already exists".
- Create an invoice field named Client Ref.
- Try to create a report field named Client Ref.
- Verify the error is "An invoice field with this name already exists".
Test 8
- Create a Collect workspace, enable Invoices, then enable Invoice fields (this upgrades to Control).
- Overview → Plan type → downgrade to Collect.
- Open Invoices and scroll to Invoice fields.
- Verify the toggle is off and the fields and add button are hidden.
- Open the create-field URL directly (/settings/workspaces/:policyID/invoices/fields/new).
- Verify access is denied.
Test 9
- Create Control workspaces A and B and enable Invoices on both.
- On A, enable Invoice fields and add no fields, bank account, or company details.
- On B, leave Invoice fields disabled.
- Copy settings from A to B.
- Verify the Invoices row is present.
Zapier Logs
Run ID: 00040eee-e2d4-a52d-43ed-0c9f36a46ea4Reacted by Matt Allen-
@mallenexpensify BZ Checklist done. Thanks
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Version Number: 9.2.30-1
Reproducible in staging?: Y
**Reproducible in production?:**Y
If this was caught during regression testing, add the test name, ID and link from TestRail: N/A
Email or phone of affected tester (no customers): sdhbhsdiuhsiudh@gmail.com
Issue reported by: Applause - Internal Team
Action Performed:
→ Supplier Address and VAT Number text type report fields appear when the workspace currency is EUR
Expected Result:
Supplier Address and VAT Number report fields will appear in the report since the report fields are present on workspace settings > Reports
Actual Result:
Supplier Address and VAT Number report fields are not shown in the report when the report fields are present on workspace settings > Reports
Workaround:
Unknown
Platforms:
Select the officially supported platforms where the issue was reproduced:
Platforms Tested:
On which of our officially supported platforms was this issue tested:Screenshots/Videos
Add any screenshot/video evidence
Bug6974515_1760449106599.eur.mp4
View all open jobs on GitHub
Upwork Automation - Do Not Edit
Issue Owner
Current Issue Owner: @mallenexpensify