Skip to content

[Due for payment 2026-10-20] [Exploratory] Web - Taxes - Inconsistent tax amount display on report with negative expenses #98098

Open

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: v9.4.51-1
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: https://test-management.browserstack.com/projects/2219752/test-runs/68133792/folder/13176730/87547482/1639586948?sort=%2Bidentifier
Email or phone of affected tester (no customers): leungbratt6+0108@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Windows 10/Chrome
App Component: Chat Report View

Action Performed:

Preconditions:
User is an Admin of a workspace
Tax settings are enabled
User has created a report with a negative expense and a positive expense with a non-zero tax rate

  1. Open the New Dot app
  2. Navigate to the Workspace chat
  3. Click on the report with 2 expenses
  4. Scroll horizontally to the tax section of the negative expense
  5. Click on the negative expense to open the details

Expected Result:

The Tax amount should display the same on the expense detail and on the report view

Actual Result:

The Tax amount display the positive on the expense detail and as a negative amount on the report view

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7228842_1786177298361.tax-negative.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Julia Ponikarchuk
Bug ID: 7228842

Issue OwnerCurrent Issue Owner: @bernhardoj

Activity

  1. applause-bot commented on Aug 9, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/8faf6eae15e6a2d0d07cc4527264c3a803e423af452b530ebc7598cfe8dc991d

  2. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 5, 2026
  3. MelvinBot commented on Sep 5, 2026

    @MelvinBot
    Contributor

    Updated 2026-09-11: Rewritten to the solution agreed in this thread — use getTaxAmount and drop the ternary, rather than the sign-reconciliation approach originally proposed. Line references refreshed to b060a99.

    Proposal

    What is the root cause of that problem?

    The expense details page throws away the sign of the tax; the report table keeps it.

    On expense reports, taxAmount is stored in Onyx with the opposite sign of what we display, so a negative expense (refund) has a positive stored taxAmount. getTaxAmount() flips it back for display.

    The Math.abs() is the bug. trjExpensify confirmed Classic shows the refund's tax as negative, and that's the semantic the rest of the codebase already assumes.

    Where the Math.abs came from

    Commit 23ec1dd ("Add Math abs for tax formatting", 2024-06-28), part of #43519 for #42114 — QA had reported tax rendering as negative while moving a track expense into a workspace. The author's stated reason, verbatim:

    I resolved the conflicts and pushed a fix for the taxes showing negative. I don't think taxes will ever be negative, so I added a Math.abs

    So it's a blanket assumption applied to fix one flow; negative expenses were never considered. The sibling Math.abs from that same PR was later narrowed to exactly the flow it was for — useTaxAmount.ts:83 gates it on isMovingTransactionFromTrackExpense. The MoneyRequestView one never got that treatment.

    Why the negative (table) value is the correct one
    • The Total column in the same row renders the refund as negative, via the same sign convention.
    • The report-level tax total adds getTaxAmount(transaction, true) per transaction (ReportUtils.ts:4757, :4770-4775). A refund's tax only reduces the report tax total if it is negative.
    • The details page is inconsistent with itself: its own Amount field renders the signed value (:355), so you see Amount -$20.00 next to Tax $1.82.

    What changes do you think we should make in order to solve the problem?

    1. Collapse the ternary at MoneyRequestView.tsx:371-374 to one line:

    const formattedTaxAmount = convertToDisplayString(transactionTaxAmount ?? 0, actualCurrency);

    transactionTaxAmount is already getTaxAmount() — getTransactionDetails derives it that way (ReportUtils.ts:5022) and is called with displayTransaction, which already resolves updatedTransaction ?? onyxTransaction (:236 → :318 → :340). So the updatedTransaction?.taxAmount !== undefined branch is redundant and wrong — it reads the raw stored (inverted-sign) value.

    Why dropping the if branch is safe, and why keeping it would be inconsistent

    updatedTransaction is only ever passed by the merge and duplicate confirmation pages (TransactionMerge/DynamicConfirmationPage.tsx:231, TransactionDuplicate/DynamicConfirmationPage.tsx:199), so the normal expense-details view always takes the else — fixing only the else does fix the reported bug.

    Both of those flows also store taxAmount in the inverted convention, so getTaxAmount is correct for them too: the duplicate page negates explicitly (:96), and the merge path computes it from the raw stored amount through the sign-preserving calculateTaxAmount (MergeTransactionUtils.ts:804).

    Keep the ternary and fix only the else, and merge/duplicate still renders an unsigned tax next to a signed amount — the same inconsistency, just moved.

    2. Do the same for the converted tax at MoneyRequestView.tsx:376.

    convertedTaxAmount carries the same inverted sign — the report tax total subtracts it (ReportUtils.ts:4774) — so its Math.abs hides the identical bug for foreign-currency expenses. There is no getter for it yet; cleanest is a getConvertedTaxAmount in TransactionUtils mirroring getTaxAmount, exposed through getTransactionDetails alongside convertedAmount, rather than negating inline.

    What alternative solutions did you explore? (Optional)

    Making TaxCell show Math.abs() so the table matches the details page. Rejected: it would put a positive tax next to a negative Total in the same row, and would no longer match the report's own tax total. trjExpensify and Classic both confirm negative is the correct display.

    Adjacent defect found while investigating (separate from this issue)

    The tax edit page renders and submits an absolute value (DynamicIOURequestStepTaxAmountPage.tsx), which then gets negated on store — so editing a refund's tax looks like it silently flips its sign. Traced through the optimistic path only, not confirmed end-to-end against the backend response.

    Verification notes

    Static analysis against b060a99. I could not drive the app in a browser in this run, so the rendered strings are unconfirmed by me — but the reporters' videos and the code path agree.

    Note the Tax column is only rendered by the wide table row, so the mismatch is visible on desktop/wide layouts.


    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/98098) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.

  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 5, 2026
  5. melvin-bot commented on Sep 5, 2026

    @melvin-bot

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

  6. melvin-bot commented on Sep 5, 2026

    @melvin-bot

    Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.

  7. bernhardoj commented on Sep 6, 2026

    @bernhardoj
    Contributor

    @jponikarchuk is this still reproducible? I can't seem to reproduce it

  8. 45 remaining items

  9. mitarachim commented on Oct 9, 2026

    @mitarachim

    Deploy Blocker #103666 was identified to be related to the PR #102175 that attempted to fix this issue.

  10. mitarachim commented on Oct 10, 2026

    @mitarachim

    Deploy Blocker #103671 was identified to be related to the PR #102175 that attempted to fix this issue.

  11. bernhardoj commented on Oct 10, 2026

    @bernhardoj
    Contributor

    Neither is a regression. I already mentioned it here. @grgia what should we do for both?

    Not a regression. It's a case that's not handled in the PR. A PR is open to handle it.

    This is a BE issue. Explained in #103666 (comment)

    Existing hidden bug as explained by Melvin here. A PR is open to handle it.

  12. jponikarchuk commented on Oct 12, 2026

    @jponikarchuk

    Deploy Blocker #103702 was identified to be related to the PR #102175 that attempted to fix this issue.

  13. melvin-bot commented on Oct 12, 2026

    @melvin-bot

    ⚠️ Looks like this issue was linked to a Deploy Blocker here

    If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

    If a regression has occurred and you are the assigned CM follow the instructions here.

    If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

  14. jponikarchuk commented on Oct 12, 2026

    @jponikarchuk

    Deploy Blocker #103707 was identified to be related to the PR #102175 that attempted to fix this issue.

  15. bernhardoj commented on Oct 12, 2026

    @bernhardoj
    Contributor

    An existing issue

    The first real regression. The stored amount is not flipped like the normal case, so I think this is really hard to catch. This is also related Expense - Tax amount is not negative after merging expenses with negative tax amount offline and will probably be fixed by the open PR.

  16. jponikarchuk commented on Oct 12, 2026

    @jponikarchuk

    Deploy Blocker #103723 was identified to be related to the PR #102175 that attempted to fix this issue.

  17. changed the title [-][Exploratory] Web - Taxes - Inconsistent tax amount display on report with negative expenses[/-] [+][Due for payment 2026-10-20] [Exploratory] Web - Taxes - Inconsistent tax amount display on report with negative expenses[/+] on Oct 13, 2026
  18. melvin-bot commented on Oct 13, 2026

    @melvin-bot

    @bernhardoj

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.7-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-10-20. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]

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

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributorNot a priorityOverdue

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions