App: [PAID] Implement and use ReportUtils.transactionThreadHasViolations(report)

  • Design Doc
  • Implementation should look like code snippet below
    • Which probably means we should connect ReportUtils to the BETAS onyx collection
    • Let’s also connect it to the TRANSACTION_VIOLATIONS and REPORT_ACTIONS Onyx collections as shown below
    • And let’s also add as shown below ReportUtils.reportHasViolations
  • Then let’s use ReportUtils.transactionThreadHasViolations
    • In SidebarUtils.ts Let’s update this
      • From: result.brickRoadIndicator = Object.keys(result.allReportErrors ?? {}).length !== 0 ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
      • To: result.brickRoadIndicator = Object.keys(result.allReportErrors ?? {}).length !== 0 || ReportUtils.transactionThreadHasViolations(report) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
      • That way src/components/LHNOptionsList/OptionRowLHN.js should show the RBR
    • In ReportUtils.shouldReportBeInOptionList above if (isInGSDMode) { we’ll add the if in the snippet below to surface the iou reports with violations on the LHN
  • And let’s use ReportUtils.reportHasViolations
    • In src/components/ReportActionItem/ReportPreview.js let’s update the code so the hasErrors value takes into account the report violations const hasErrors = (hasReceipts && ReportUtils.hasMissingSmartscanFields(props.iouReportID)) || ReportUtils.reportHasViolations(props.iouReportID);
const transactionViolations = {};
Onyx.connect({
    key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
    callback: (violations, key) => {
        if (!key || !violations) {
            return;
        }

        const transactionID = CollectionUtils.extractCollectionItemID(key);
        transactionViolations[transactionID] = violations;
    },
});

const reportActions = {};
Onyx.connect({
    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
    callback: (actions, key) => {
        if (!key || !actions) {
            return;
        }

        const reportID = CollectionUtils.extractCollectionItemID(key);
        reportActions[reportID] = actions;
    },
});
function transactionThreadHasViolations(report) {
    if (!permissions.canUseViolations()) {
        return false;
    }
    if (!report.parentReportActionID ?? 0) {
        return false;
    }
    const parentReportAction = lodashGet(reportActions, `${report.parentReportID}.${report.parentReportActionID}`);
    if (!parentReportAction) {
        return false;
    }
    const transactionID = parentReportAction['originalMessage']['IOUTransactionID'] ?? 0;
    if (!transactionID) {
        return false;
    }
    const reportID = parentReportAction['originalMessage']['IOUReportID'] ?? 0;
    if (!reportID) {
        return false;
    }
    if (!isCurrentUserSubmitter(reportID)) {
        return false;
    }
    return transactionHasViolation(transactionID);
}
function transactionHasViolation(transactionID) {
    const violations = lodashGet(transactionViolations, transactionID, []);
    return _.some(violations, violation => violation.type === 'violation');
}
function reportHasViolations(reportID) {
    let transactions = TransactionUtils.getAllReportTransactions(reportID);
    return _.some(transactions, (transaction) => transactionHasViolation(transaction.transactionID));
}

// Always show IOU reports with violations
if (isExpenseRequest(report) && transactionThreadHasViolations(report)) {
    return true;
}

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Comments: 31 (20 by maintainers)

Most upvoted comments

The solution for this issue has been 🚀 deployed to production 🚀 in version 1.4.28-0 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 2024-01-28. 🎊

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

  • @cdanwards does not require payment (Contractor)

Awesome! @cdanwards can you add another condition to transactionThreadHasViolations to return false if the report is on a state that isn’t open or processing? We only wanna show RBR on the left hand nav to the report submitter, and only if the report is open or processing