Skip to content

[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

@lanitochka17

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:

  1. Go to staging.new.expensify.com
  2. Create an EUR workspace
  3. Go to workspace settings > Reports
  4. Enable Report fields
  5. Click Upgrade > Got it, thanks
    → Supplier Address and VAT Number text type report fields appear when the workspace currency is EUR
  6. Go to workspace chat
  7. Create an empty report
  8. Open the empty report
  9. Create an expense in the empty report

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:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari
  • MacOS: Desktop
Platforms Tested: On which of our officially supported platforms was this issue tested:
  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Add any screenshot/video evidence
Bug6974515_1760449106599.eur.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021979200514033151425
  • Upwork Job ID: 1979200514033151425
  • Last Price Increase: 2025-10-24
Issue OwnerCurrent Issue Owner: @mallenexpensify

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Oct 14, 2025
  2. melvin-bot commented on Oct 14, 2025

    @melvin-bot

    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.

  3. ShridharGoel commented on Oct 14, 2025

    @ShridharGoel
    Contributor

    🚨 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.

    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?

    1. 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,
        ),
    );
    1. 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) => ({
                ...
            })),
        ];
    1. Allow the create-field route to carry an optional target query 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],
    );
    1. 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}
        ...
    />
    1. 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
  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 17, 2025
  5. 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
  6. melvin-bot commented on Oct 17, 2025

    @melvin-bot
  7. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Oct 17, 2025
  8. melvin-bot commented on Oct 17, 2025

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @rojiphil (External)

  9. abekkala commented on Oct 17, 2025

    @abekkala
    Contributor

    @rojiphil we did already receive a proposal for this one. Can you give it a look? thanks!

  10. abekkala commented on Oct 20, 2025

    @abekkala
    Contributor

    @rojiphil when you have a moment can you please review the two proposals? Thanks!

  11. 188 remaining items

  12. 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
  13. melvin-bot commented on Sep 30, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  14. mallenexpensify commented on Oct 1, 2026

    @mallenexpensify
    Contributor

    @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.

  15. rojiphil commented on Oct 1, 2026

    @rojiphil
    Contributor

    #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 @mallenexpensify

    What 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 areInvoiceFieldsEnabled or 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 fieldID in a shared fieldList. 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.

  16. mollfpr commented on Oct 1, 2026

    @mollfpr
    Contributor

    Agreed, $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.

  17. ShridharGoel commented on Oct 1, 2026

    @ShridharGoel
    Contributor

    @mallenexpensify No BE hours were used for the FE work here. This was started before joining the BE team.

  18. mallenexpensify commented on Oct 3, 2026

    @mallenexpensify
    Contributor

    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

  19. ShridharGoel commented on Oct 3, 2026

    @ShridharGoel
    Contributor

    @rojiphil was the reviewer on this, so I think he would fill the checklist.

  20. mallenexpensify commented on Oct 3, 2026

    @mallenexpensify
    Contributor

    Updated payment summary to inc. proper reviewer

  21. rojiphil commented on Oct 4, 2026

    @rojiphil
    Contributor

    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

    Regression Test Proposal

    Precondition:

    Test:

    Do we agree 👍 or 👎

    Test 1

    1. Go to workspace settings.
    2. Turn on invoices.
    3. Go to the Invoices tab.
    4. Verify the Invoice fields section is visible.
    5. Add a new field.
    6. Edit the added field.
    7. Create an invoice and verify the invoice fields are visible.

    Test 2

    1. Enable Invoices, enable Invoice fields, and create a field.
    2. Workspaces tab → 3-dot menu → Duplicate workspace → Next → Continue.
    3. Open the duplicated workspace → Invoices.
    4. Verify Invoice fields are enabled.

    Test 3

    1. Invoices → enable Invoice fields → add a text field.
    2. Reports → enable Report fields → add a text field → delete it.
    3. Return to Invoices.
    4. Verify the invoice field is still there.
    5. The Offline tests section on both pulls was left empty.

    Test 4

    1. Sign in to two accounts.
    2. On account B, enable invoices and enter invoice details.
    3. Send an invoice to account A.
    4. Enable Invoice fields and add a text field with no initial value.
    5. Confirm the LHN shows a Fix badge.
    6. On account A, pay the invoice.
    7. On account B, open the paid invoice and recheck the LHN.
    8. Verify the Fix badge is not shown for the paid invoice.

    Test 5

    1. Create workspaces A and B. On A, enable invoices, enter company name and website, and create one invoice field.
    2. Duplicate workspace A and confirm the Invoices row shows "1 invoice fields".
    3. Copy settings from A to B.
    4. Verify the Invoices row shows "1 invoice fields".

    Test 6

    1. Enable Invoice fields and create a text field.
    2. Enable Report fields and try to create a text field with the same name.
    3. Verify the name is rejected.

    Test 7

    1. Create a report field named PO Number.
    2. Try to create an invoice field named PO Number.
    3. Verify the error is "A report field with this name already exists".
    4. Create an invoice field named Client Ref.
    5. Try to create a report field named Client Ref.
    6. Verify the error is "An invoice field with this name already exists".

    Test 8

    1. Create a Collect workspace, enable Invoices, then enable Invoice fields (this upgrades to Control).
    2. Overview → Plan type → downgrade to Collect.
    3. Open Invoices and scroll to Invoice fields.
    4. Verify the toggle is off and the fields and add button are hidden.
    5. Open the create-field URL directly (/settings/workspaces/:policyID/invoices/fields/new).
    6. Verify access is denied.

    Test 9

    1. Create Control workspaces A and B and enable Invoices on both.
    2. On A, enable Invoice fields and add no fields, bank account, or company details.
    3. On B, leave Invoice fields disabled.
    4. Copy settings from A to B.
    5. Verify the Invoices row is present.
    Zapier Logs Run ID: 00040eee-e2d4-a52d-43ed-0c9f36a46ea4
  22. rojiphil commented on Oct 4, 2026

    @rojiphil
    Contributor

    @mallenexpensify BZ Checklist done. Thanks

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

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions