Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Navigation from '@libs/Navigation/Navigation';
import {getReportAction} from '@libs/ReportActionsUtils';
import {canAddTransaction as canAddTransactionUtil, getAddExpenseDropdownOptions} from '@libs/ReportUtils';
import {createAndOpenSearchTransactionThread, getColumnsToShow, getSections} from '@libs/SearchUIUtils';
import {getTransactionViolations} from '@libs/TransactionUtils';
import variables from '@styles/variables';
import {setActiveTransactionThreadIDs} from '@userActions/TransactionThreadNavigation';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -351,7 +352,7 @@ function TransactionGroupListItem<TItem extends ListItem>({
key={transaction.transactionID}
report={transaction.report}
transactionItem={transaction}
violations={violations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`]}
violations={getTransactionViolations(transaction, violations)}
isSelected={!!transaction.isSelected}
dateColumnSize={dateColumnSize}
amountColumnSize={amountColumnSize}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import useSyncFocus from '@hooks/useSyncFocus';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {handleActionButtonPress as handleActionButtonPressUtil} from '@libs/actions/Search';
import {getTransactionViolations} from '@libs/TransactionUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -74,6 +75,8 @@ function TransactionListItem<TItem extends ListItem>({
};
}, [transactionItem]);

const transactionViolations = useMemo(() => getTransactionViolations(transactionItem, violations), [transactionItem, violations]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We missed filtering violations based on users via shouldShowViolation, which we fixed in #70685


const handleActionButtonPress = useCallback(() => {
handleActionButtonPressUtil(
currentSearchHash,
Expand Down Expand Up @@ -148,7 +151,7 @@ function TransactionListItem<TItem extends ListItem>({
shouldShowCheckbox={!!canSelectMultiple}
style={[styles.p3, shouldUseNarrowLayout ? styles.pt2 : {}]}
areAllOptionalColumnsHidden={areAllOptionalColumnsHidden}
violations={violations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionItem.transactionID}`]}
violations={transactionViolations}
/>
</PressableWithFeedback>
</OfflineWithFeedback>
Expand Down
28 changes: 23 additions & 5 deletions src/hooks/useTransactionsAndViolationsForReport.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import {useMemo} from 'react';
import {useAllReportsTransactionsAndViolations} from '@components/OnyxListItemProvider';
import CONST from '@src/CONST';
import {getTransactionViolations} from '@libs/TransactionUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import type {TransactionViolations} from '@src/types/onyx';
import type {ReportTransactionsAndViolations} from '@src/types/onyx/DerivedValues';

const DEFAULT_RETURN_VALUE: ReportTransactionsAndViolations = {transactions: {}, violations: {}};

function useTransactionsAndViolationsForReport(reportID?: string) {
const allReportsTransactionsAndViolations = useAllReportsTransactionsAndViolations();

if (!reportID) {
return DEFAULT_RETURN_VALUE;
}
const {transactions, violations} = reportID ? (allReportsTransactionsAndViolations?.[reportID] ?? DEFAULT_RETURN_VALUE) : DEFAULT_RETURN_VALUE;
Comment thread
s77rt marked this conversation as resolved.

return allReportsTransactionsAndViolations?.[reportID ?? CONST.DEFAULT_NUMBER_ID] ?? DEFAULT_RETURN_VALUE;
const transactionsAndViolations = useMemo<ReportTransactionsAndViolations>(() => {
const filteredViolations = Object.keys(violations).reduce(
(filteredTransactionViolations, transactionViolationKey) => {
const transactionID = transactionViolationKey.split('_').at(1) ?? '';
const transaction = transactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];

// This is our accumulator, it's okay to reassign
// eslint-disable-next-line no-param-reassign
filteredTransactionViolations[transactionViolationKey] = getTransactionViolations(transaction, violations) ?? [];
return filteredTransactionViolations;
},
{} as Record<string, TransactionViolations>,
);

return {transactions, violations: filteredViolations};
}, [transactions, violations]);

return transactionsAndViolations;
}

export default useTransactionsAndViolationsForReport;
2 changes: 1 addition & 1 deletion src/libs/ReportPrimaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ function isRemoveHoldAction(report: Report, chatReport: OnyxEntry<Report>, repor
}

function isReviewDuplicatesAction(report: Report, reportTransactions: Transaction[]) {
const hasDuplicates = reportTransactions.some((transaction) => isDuplicate(transaction));
const hasDuplicates = reportTransactions.some((transaction) => isDuplicate(transaction, true));

if (!hasDuplicates) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportSecondaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ function isApproveAction(report: Report, reportTransactions: Transaction[], viol
return false;
}
const isExpenseReport = isExpenseReportUtils(report);
const reportHasDuplicatedTransactions = reportTransactions.some((transaction) => isDuplicate(transaction));
const reportHasDuplicatedTransactions = reportTransactions.some((transaction) => isDuplicate(transaction, true));

if (isExpenseReport && isProcessingReport && reportHasDuplicatedTransactions) {
return true;
Expand Down
Loading