Skip to content

[Due for payment 2025-10-21] [$250] Expense - Review and red dot display after submit manual expense which add picture to receipt #70038

Closed

Description

@jponikarchuk

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: v9.2.2-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from TestRail: Explore
Email or phone of affected tester (no customers): N/A
Issue reported by: Applause Internal Team
Device used: Win 11/Chrome
App Component: Money Requests

Action Performed:

Precondition: Create a workspace, enable Delay submissions manually, Add approvals and Make or track payments

  1. Open https://staging.new.expensify.com
  2. Go to workspace chat
  3. Create a manual expense
  4. Click on this expense
  5. Upload a picture to receipt
  6. Click Submit
  7. Return to expense preview
  8. Click on Review

Expected Result:

Review button only displays if have error message

Actual Result:

Review button is displayed on expense preview and red dot on LHN but no error message in expense detail

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

1.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021965736867491332301
  • Upwork Job ID: 1965736867491332301
  • Last Price Increase: 2025-09-10
  • Automatic offers:
    • abzokhattab | Contributor | 108744342
Issue OwnerCurrent Issue Owner: @zanyrenney

Activity

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

    @melvin-bot

    Triggered auto assignment to @zanyrenney (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. daledah commented on Sep 7, 2025

    @daledah
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    Review and red dot display after submit manual expense which add picture to receipt

    What is the root cause of that problem?

    we have this violation when the user added the image manual

    Image

    Then we will return as false in canApprove function because of hasAnyViolations is true

    return isExpense && isProcessing && !!isApprovalEnabled && (!hasAnyViolations || !shouldConsiderViolations) && reportTransactions.length > 0 && isCurrentUserManager;

    Additionally we are not showing the RECEIPT_NOT_SMART_SCANNED violation to the submitter here

    if (violationName === CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED) {
    return isPolicyMember && !isSubmitter && !isReportOpen;
    }

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

    We should also show this violation to the submitter

        if (violationName === CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED) {
            return isPolicyMember && !isReportOpen;
        }
    

    if (violationName === CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED) {
    return isPolicyMember && !isSubmitter && !isReportOpen;
    }

    Note: We can review the condition here, we can add approver, admin... in this condition depending on the decision of the internal team

    What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

    We can write a test function for the shouldShowViolation function to cover this case

    What alternative solutions did you explore? (Optional)

  4. abzokhattab commented on Sep 7, 2025

    @abzokhattab
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    Review button and red dot display after submit manual expense which add picture to receipt, but no error message in expense detail

    What is the root cause of that problem?

    if (violationName === CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED) {
    return isPolicyMember && !isSubmitter && !isReportOpen;
    }

    • This causes hasAnyViolations to return true (violations exist) but the submitter sees no error messages (violations not visible), resulting in the Review button showing incorrectly

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

    • Update the canReview function to check for violations that are actually visible to the current user by using the existing shouldShowViolation logic:

    • to do that, we need to add a helper function (can be added as a util function)
    function hasVisibleViolationsForUser(report: Report, violations: OnyxCollection<TransactionViolation[]>, policy?: Policy, transactions?: Transaction[]): boolean {
        if (!violations || !transactions) {
            return false;
        }
    
        return transactions.some((transaction) => {
            const transactionViolations = violations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`];
            if (!transactionViolations) {
                return false;
            }
    
            return transactionViolations.some((violation) => {
                return shouldShowViolation(report, policy, violation.name);
            });
        });
    }
    • then inside the canReview function use:
        const hasVisibleViolations = hasAnyViolations && hasVisibleViolationsForUser(report, violations, policy, transactions);

    and update this to :

        if (
            !hasVisibleViolations ||

    What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

    • Test that Review button doesn't show for submitters when RECEIPT_NOT_SMART_SCANNED violation exists but is hidden
    • Test that Review button shows for non-submitters when RECEIPT_NOT_SMART_SCANNED violation is visible

    What alternative solutions did you explore? (Optional)

    NA

  5. lorretheboy commented on Sep 8, 2025

    @lorretheboy
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    Expense - Review and red dot display after submit manual expense which add picture to receipt

    What is the root cause of that problem?

    The user was seeing a receiptNotSmartScanned violation (red dot indicator) even though they were the submitter of the expense. According to the existing shouldShowViolation logic in TransactionUtils.ts, this violation should NOT be shown to submitters:

    if (violationName === CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED) {
    return isPolicyMember && !isSubmitter && !isReportOpen;
    }

    However, the violation was still appearing in places:
    Report Preview - Showing "Review" button instead of "Submit/Approve"
    Left Hand Navigation (LHN) - Showing red dot indicator
    Search preview
    ...

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

    1. Fix Report Preview - Showing "Review" button instead of "Submit/Approve"

    Create util function for check visible vilotions for LHN

    function hasVisibleViolationsForLHN(report: OnyxEntry<Report>, transactionViolations: OnyxCollection<TransactionViolation[]>, policy?: OnyxEntry<Policy>): boolean {
        if (!report || !transactionViolations) {
            return false;
        }
    
        const transactions = getReportTransactions(report.reportID);
        return transactions.some((transaction) => {
            const violationsForTransaction = transactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`];
            if (!violationsForTransaction) {
                return false;
            }
    
            return violationsForTransaction.some((violation) => {
                return shouldShowViolation(report, policy, violation.name);
            });
        });
    }

    Then update condition to show violations RBR In LHN to match with report details

        const policy = getPolicy(report.policyID);
    
        // If any report has a violation that should be visible to the current user, then it should have a RBR
        const potentialReports = Object.values(reportsByPolicyID[report.policyID] ?? {}) ?? [];
        return potentialReports.some((potentialReport) => {
            if (!potentialReport || isInvoiceReport(potentialReport)) {
                return false;
            }
    
            return hasVisibleViolationsForLHN(potentialReport, transactionViolations, policy);
        });

    App/src/libs/ReportUtils.ts

    Lines 8140 to 8153 in 9b653ae

    // If any report has a violation, then it should have a RBR
    const potentialReports = Object.values(reportsByPolicyID[report.policyID] ?? {}) ?? [];
    return potentialReports.some((potentialReport) => {
    if (!potentialReport) {
    return false;
    }
    return (
    !isInvoiceReport(potentialReport) &&
    (hasViolations(potentialReport.reportID, transactionViolations, true) ||
    hasWarningTypeViolations(potentialReport.reportID, transactionViolations, true) ||
    hasNoticeTypeViolations(potentialReport.reportID, transactionViolations, true))
    );
    });

    1. Fix: Left Hand Navigation (LHN) - Showing red dot indicator

    Create function to check visible for violations for user

    function hasVisibleViolationsForUser(report: Report, violations: OnyxCollection<TransactionViolation[]>, policy?: Policy, transactions?: Transaction[]): boolean {
        if (!violations || !transactions) {
            return false;
        }
    
        return transactions.some((transaction) => {
            const transactionViolations = violations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`];
            if (!transactionViolations) {
                return false;
            }
    
            return transactionViolations.some((violation) => {
                return shouldShowViolation(report, policy, violation.name);
            });
        });
    }
        const hasVisibleViolations = hasAnyViolations && hasVisibleViolationsForUser(report, violations, policy, transactions);
    
    ...
    
        // Update hasAnyViolations to use hasVisibleViolations in if statement

    if (
    !hasAnyViolations ||
    isReimbursed ||
    (!(isSubmitter && isOpen && policy?.areWorkflowsEnabled) &&
    !canApprove(report, violations, policy, transactions, false) &&
    !canPay(report, violations, isReportArchived, policy, policy, false))
    ) {

    1. Fix: Search preview
    function hasVisibleViolationsForSearch(report: OnyxEntry<OnyxTypes.Report>, violations: OnyxCollection<OnyxTypes.TransactionViolation[]>, policy?: OnyxEntry<OnyxTypes.Policy>, transactions?: OnyxTypes.Transaction[]): boolean {
        if (!report || !violations || !transactions) {
            return false;
        }
    
        return transactions.some((transaction) => {
            const transactionViolations = violations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`];
            if (!transactionViolations) {
                return false;
            }
    
            return transactionViolations.some((violation) => {
                return shouldShowViolation(report, policy, violation.name);
            });
        });
    }
    
    ....
        const hasAnyViolationsForReport = hasAnyViolations(report.reportID, allViolations, allReportTransactions);
        const hasVisibleViolationsForReport = hasAnyViolationsForReport && hasVisibleViolationsForSearch(report, allViolations, policy, allReportTransactions);
        if ((isSubmitter || isApprover || isAdmin) && hasVisibleViolationsForReport) {

    if ((isSubmitter || isApprover || isAdmin) && hasAnyViolations(report.reportID, allViolations, allReportTransactions)) {

    We need to do similar to all other places that showing error indicator

    Note: We may have some minor changes and refactor which can be discussed in PR phase if needed

    Before:

    Image

    After:

    Image

    What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

    Update tests to cover this case for LHN and report preview

    What alternative solutions did you explore? (Optional)

    Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.

  6. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 10, 2025
  7. changed the title [-]Expense - Review and red dot display after submit manual expense which add picture to receipt[/-] [+][$250] Expense - Review and red dot display after submit manual expense which add picture to receipt[/+] on Sep 10, 2025
  8. melvin-bot commented on Sep 10, 2025

    @melvin-bot
  9. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Sep 10, 2025
  10. melvin-bot commented on Sep 10, 2025

    @melvin-bot

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

  11. 23 remaining items

  12. added
    Awaiting PaymentAuto-added when associated PR is deployed to production
    and removed on Oct 14, 2025
  13. changed the title [-][$250] Expense - Review and red dot display after submit manual expense which add picture to receipt[/-] [+][Due for payment 2025-10-21] [$250] Expense - Review and red dot display after submit manual expense which add picture to receipt[/+] on Oct 14, 2025
  14. melvin-bot commented on Oct 14, 2025

    @melvin-bot

    Reviewing label has been removed, please complete the "BugZero Checklist".

  15. melvin-bot commented on Oct 14, 2025

    @melvin-bot

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.2.30-6 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 2025-10-21. 🎊

    For reference, here are some details about the assignees on this issue:

  16. melvin-bot commented on Oct 14, 2025

    @melvin-bot

    @brunovjk @zanyrenney The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero 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]

  17. brunovjk commented on Oct 20, 2025

    @brunovjk
    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 PR directly introduced this bug; it's more of an edge case. We've updated the violation filter based on user visibility.

    • [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:

    • [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

    Test:

    1. Create a new workspace
    2. Create a new manual expense
    3. Go to expnse details
    4. Add receipt
    5. Submit the expense
    6. Go to expense preview and validate there is no error indicator
    7. Go to Left Hand Navigation (LHN) and validate there is no error indicator
    8. Go to Reports > Expenses and validate there is no error indicator

    Do we agree 👍 or 👎

  18. zanyrenney commented on Oct 22, 2025

    @zanyrenney
    Contributor

    Payment summary

    @abzokhattab requires payment automatic offer (Contributor) - paid via job on Upwork.
    @brunovjk requires payment through NewDot Manual Requests - please request $250 via ND.

  19. garrettmknight commented on Oct 24, 2025

    @garrettmknight
    Contributor

    $250 approved for @brunovjk

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

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions