Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
924b2e3
add `canReject` to SearchTransaction type
lakchote Dec 8, 2025
cb1b33b
add `canReject` to SelectedTransactionInfo
lakchote Dec 8, 2025
fc3a4f0
add `canReject` to selection mappings
lakchote Dec 8, 2025
3534544
replace prefetching with `canReject` check
lakchote Dec 8, 2025
ef52fa7
add `canReject` to test mock data
lakchote Dec 8, 2025
edb094a
add `canReject` to test mock data
lakchote Dec 8, 2025
db81a18
add `canReject` to test mock data
lakchote Dec 8, 2025
5de885e
add `canReject` to test mock data
lakchote Dec 8, 2025
f1bd51a
Merge remote-tracking branch 'origin/main' into lucien/use-canReject-…
lakchote Dec 8, 2025
5656d08
update expected property count in test for `canReject`
lakchote Dec 8, 2025
98d7ade
remove `canReject` from SearchTransaction type
lakchote Dec 9, 2025
62b0485
compute `canReject` dynamically via `canRejectReportAction`
lakchote Dec 9, 2025
d6d4e13
remove `canReject` from test mocks
lakchote Dec 9, 2025
dd52b64
Merge branch 'main' into lucien/add-Search-canReject-property
lakchote Dec 9, 2025
0712f04
fix style
lakchote Dec 9, 2025
d38c2bc
Merge branch 'main' into lucien/add-Search-canReject-property
lakchote Dec 9, 2025
632fc5c
fixes to undo the soft revert
lakchote Dec 9, 2025
2fdff4b
fix style
lakchote Dec 9, 2025
08a796d
use `report.transactionCount` for accurate all-selected check
lakchote Dec 10, 2025
f252561
Merge branch 'main' into lucien/use-canReject-from-search
lakchote Dec 10, 2025
7eae475
hide reject option for expense-report search
lakchote Dec 10, 2025
d02d7a8
Merge remote-tracking branch 'origin/main' into lucien/use-canReject-…
lakchote Dec 10, 2025
826c2c5
fix style
lakchote Dec 10, 2025
938b536
fixes
lakchote Dec 10, 2025
0d0a8e1
add reject transactions route for money request report
lakchote Dec 10, 2025
f9f291b
add screen mapping for reject transactions route
lakchote Dec 10, 2025
09abd73
add `rejectMoneyRequestInBulkFromReport` function
lakchote Dec 10, 2025
005d91c
update reject navigation to use report route
lakchote Dec 10, 2025
ff6c641
handle both reject routes with bulk API support
lakchote Dec 10, 2025
6da6bf1
fix style
lakchote Dec 10, 2025
d4a11b5
add `hasTransactionBeenRejected` helper
lakchote Dec 10, 2025
bd564bf
simplify `rejectMoneyRequestsOnSearch` type
lakchote Dec 10, 2025
df3f786
remove duplicate bulk reject functions
lakchote Dec 10, 2025
2c32a77
use `hasTransactionBeenRejected` helper
lakchote Dec 10, 2025
619943c
reuse `rejectMoneyRequestsOnSearch` for both views
lakchote Dec 10, 2025
2a87aeb
filter out already rejected transactions
lakchote Dec 10, 2025
ce4a02d
add education modal for bulk reject
lakchote Dec 10, 2025
407081b
fix style
lakchote Dec 10, 2025
c71f225
fix offline delete count in bulk reject
lakchote Dec 10, 2025
fd1d444
fix style
lakchote Dec 10, 2025
d865449
add `REJECT_BULK` action type for bulk reject
lakchote Dec 11, 2025
cf2b64f
remove redundant `isReportReimbursed` check
lakchote Dec 11, 2025
99b3a16
fix bulk reject education modal navigation
lakchote Dec 11, 2025
2b0c327
use Partial type for secondary actions implementation
lakchote Dec 11, 2025
5b9cb3b
fix style
lakchote Dec 11, 2025
506bbf3
fix lint error for default ID value
lakchote Dec 11, 2025
4479bae
Merge branch 'main' into lucien/use-canReject-from-search
lakchote Dec 11, 2025
a641f4c
use CONST for reject action value
lakchote Dec 11, 2025
154d468
match options by value instead of text
lakchote Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,7 @@ const CONST = {
VIEW_DETAILS: 'viewDetails',
DELETE: 'delete',
REJECT: 'reject',
REJECT_BULK: 'rejectBulk',
MERGE: 'merge',
DUPLICATE: 'duplicate',
},
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ const ROUTES = {
return getUrlWithBackToParam(baseRoute, backTo);
},
},
SEARCH_MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS: {
route: 'search/r/:reportID/reject',
getRoute: ({reportID}: {reportID: string}) => `search/r/${reportID}/reject` as const,
},
TRANSACTION_HOLD_REASON_RHP: 'search/hold',
SEARCH_REJECT_REASON_RHP: 'search/reject',
MOVE_TRANSACTIONS_SEARCH_RHP: 'search/move-transactions',
Expand Down
23 changes: 20 additions & 3 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ function MoneyReportHeader({
const [isDownloadErrorModalVisible, setIsDownloadErrorModalVisible] = useState(false);
const [isHoldEducationalModalVisible, setIsHoldEducationalModalVisible] = useState(false);
const [rejectModalAction, setRejectModalAction] = useState<ValueOf<
typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD | typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT
typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD | typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT | typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT_BULK
> | null>(null);

const {selectedTransactionIDs, removeTransaction, clearSelectedTransactions, currentSearchQueryJSON, currentSearchKey, currentSearchHash} = useSearchContext();
Expand Down Expand Up @@ -682,6 +682,11 @@ function MoneyReportHeader({
if (requestParentReportAction) {
changeMoneyRequestHoldStatus(requestParentReportAction);
}
} else if (rejectModalAction === CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT_BULK) {
dismissRejectUseExplanation();
if (moneyRequestReport?.reportID) {
Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS.getRoute({reportID: moneyRequestReport.reportID}));
}
} else {
dismissRejectUseExplanation();
if (requestParentReportAction) {
Expand Down Expand Up @@ -1451,15 +1456,27 @@ function MoneyReportHeader({

const selectedTransactionsOptions = useMemo(() => {
return originalSelectedTransactionsOptions.map((option) => {
if (option.text === translate('common.delete')) {
if (option.value === CONST.REPORT.SECONDARY_ACTIONS.DELETE) {
return {
...option,
onSelected: showDeleteModal,
};
}
if (option.value === CONST.REPORT.SECONDARY_ACTIONS.REJECT) {
return {
...option,
onSelected: () => {
if (dismissedRejectUseExplanation) {
option.onSelected?.();
} else {
setRejectModalAction(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT_BULK);
}
},
};
}
return option;
});
}, [originalSelectedTransactionsOptions, translate, showDeleteModal]);
}, [originalSelectedTransactionsOptions, showDeleteModal, dismissedRejectUseExplanation]);

const shouldShowSelectedTransactionsButton = !!selectedTransactionsOptions.length && !transactionThreadReportID;

Expand Down
6 changes: 4 additions & 2 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
import HoldOrRejectEducationalModal from './HoldOrRejectEducationalModal';
import HoldSubmitterEducationalModal from './HoldSubmitterEducationalModal';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';

Check warning on line 74 in src/components/MoneyRequestHeader.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'./Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import LoadingBar from './LoadingBar';
import type {MoneyRequestHeaderStatusBarProps} from './MoneyRequestHeaderStatusBar';
import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar';
Expand Down Expand Up @@ -336,7 +336,9 @@
setRejectModalAction(null);
};

const secondaryActionsImplementation: Record<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>, DropdownOption<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>>> = {
const secondaryActionsImplementation: Partial<
Record<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>, DropdownOption<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>>>
> = {
[CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD]: {
text: translate('iou.hold'),
icon: Expensicons.Stopwatch,
Expand Down Expand Up @@ -442,7 +444,7 @@
},
};

const applicableSecondaryActions = secondaryActions.map((action) => secondaryActionsImplementation[action]);
const applicableSecondaryActions = secondaryActions.map((action) => secondaryActionsImplementation[action]).filter((action): action is NonNullable<typeof action> => !!action);
const shouldDisplayNarrowMoreButton = !shouldUseNarrowLayout || (wideRHPRouteKeys.length > 0 && !isSmallScreenWidth);

return (
Expand Down
27 changes: 21 additions & 6 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import isSearchTopmostFullScreenRoute from '@libs/Navigation/helpers/isSearchTop
import type {PlatformStackNavigationProp} from '@libs/Navigation/PlatformStackNavigation/types';
import Performance from '@libs/Performance';
import {isSplitAction} from '@libs/ReportSecondaryActionUtils';
import {canEditFieldOfMoneyRequest, canHoldUnholdReportAction, isOneTransactionReport, selectFilteredReportActions} from '@libs/ReportUtils';
import {canEditFieldOfMoneyRequest, canHoldUnholdReportAction, canRejectReportAction, isOneTransactionReport, selectFilteredReportActions} from '@libs/ReportUtils';
import {buildCannedSearchQuery, buildSearchQueryJSON, buildSearchQueryString} from '@libs/SearchQueryUtils';
import {
createAndOpenSearchTransactionThread,
Expand Down Expand Up @@ -96,14 +96,18 @@ function mapTransactionItemToSelectedEntry(
item: TransactionListItemType,
itemTransaction: OnyxEntry<Transaction>,
originalItemTransaction: OnyxEntry<Transaction>,
currentUserLogin: string,
outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue,
): [string, SelectedTransactionInfo] {
const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy);
const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false;

return [
item.keyForList,
{
isSelected: true,
canDelete: item.canDelete,
canReject: canRejectRequest,
canHold: canHoldRequest,
isHeld: isOnHold(item),
canUnhold: canUnholdRequest,
Expand Down Expand Up @@ -179,6 +183,7 @@ function prepareTransactionsList(
itemTransaction: OnyxEntry<Transaction>,
originalItemTransaction: OnyxEntry<Transaction>,
selectedTransactions: SelectedTransactions,
currentUserLogin: string,
outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue,
) {
if (selectedTransactions[item.keyForList]?.isSelected) {
Expand All @@ -188,12 +193,14 @@ function prepareTransactionsList(
}

const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy);
const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false;

return {
...selectedTransactions,
[item.keyForList]: {
isSelected: true,
canDelete: item.canDelete,
canReject: canRejectRequest,
canHold: canHoldRequest,
isHeld: isOnHold(item),
canUnhold: canUnholdRequest,
Expand Down Expand Up @@ -512,6 +519,7 @@ function Search({
transactionItem,
transactionItem.policy,
);
const canRejectRequest = email && transactionItem.report ? canRejectReportAction(email, transactionItem.report, transactionItem.policy) : false;

const itemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionItem.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
Expand All @@ -536,6 +544,7 @@ function Search({
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
isSelected: areAllMatchingItemsSelected || selectedTransactions[transactionItem.transactionID]?.isSelected || isExpenseReportType,
canDelete: transactionItem.canDelete,
canReject: canRejectRequest,
reportID: transactionItem.reportID,
policyID: transactionItem.report?.policyID,
amount: transactionItem.modifiedAmount ?? transactionItem.amount,
Expand All @@ -562,6 +571,7 @@ function Search({
transactionItem,
transactionItem.policy,
);
const canRejectRequest = email && transactionItem.report ? canRejectReportAction(email, transactionItem.report, transactionItem.policy) : false;

const itemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionItem.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
Expand All @@ -586,6 +596,7 @@ function Search({
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
isSelected: areAllMatchingItemsSelected || selectedTransactions[transactionItem.transactionID].isSelected,
canDelete: transactionItem.canDelete,
canReject: canRejectRequest,
reportID: transactionItem.reportID,
policyID: transactionItem.report?.policyID,
amount: transactionItem.modifiedAmount ?? transactionItem.amount,
Expand Down Expand Up @@ -666,7 +677,10 @@ function Search({
}
const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${item.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
setSelectedTransactions(prepareTransactionsList(item, itemTransaction, originalItemTransaction, selectedTransactions, outstandingReportsByPolicyID), filteredData);
setSelectedTransactions(
prepareTransactionsList(item, itemTransaction, originalItemTransaction, selectedTransactions, email ?? '', outstandingReportsByPolicyID),
filteredData,
);
return;
}

Expand All @@ -691,14 +705,14 @@ function Search({
.map((transactionItem) => {
const itemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionItem.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, outstandingReportsByPolicyID);
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, email ?? '', outstandingReportsByPolicyID);
}),
),
},
filteredData,
);
},
[setSelectedTransactions, selectedTransactions, filteredData, transactions, outstandingReportsByPolicyID, searchResults?.data],
[setSelectedTransactions, selectedTransactions, filteredData, transactions, outstandingReportsByPolicyID, searchResults?.data, email],
);

const onSelectRow = useCallback(
Expand Down Expand Up @@ -915,7 +929,7 @@ function Search({
.map((transactionItem) => {
const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionItem.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, outstandingReportsByPolicyID);
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, email ?? '', outstandingReportsByPolicyID);
}),
),
),
Expand All @@ -932,7 +946,7 @@ function Search({
.map((transactionItem) => {
const itemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionItem.transactionID}`] as OnyxEntry<Transaction>;
const originalItemTransaction = searchResults?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${itemTransaction?.comment?.originalTransactionID}`];
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, outstandingReportsByPolicyID);
return mapTransactionItemToSelectedEntry(transactionItem, itemTransaction, originalItemTransaction, email ?? '', outstandingReportsByPolicyID);
}),
),
filteredData,
Expand All @@ -947,6 +961,7 @@ function Search({
transactions,
outstandingReportsByPolicyID,
searchResults?.data,
email,
]);

const onLayout = useCallback(() => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/Search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ type SelectedTransactionInfo = {
/** If the transaction can be deleted */
canDelete: boolean;

/** If the transaction can be rejected */
canReject: boolean;

/** If the transaction can be put on hold */
canHold: boolean;

Expand Down
19 changes: 17 additions & 2 deletions src/hooks/useSelectedTransactionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
canDeleteTransaction,
canEditFieldOfMoneyRequest,
canHoldUnholdReportAction,
canRejectReportAction,
canUserPerformWriteAction as canUserPerformWriteActionReportUtils,
getReportOrDraftReport,
isInvoiceReport,
isMoneyRequestReport as isMoneyRequestReportUtils,
isTrackExpenseReport,
} from '@libs/ReportUtils';
import {getOriginalTransactionWithSplitInfo} from '@libs/TransactionUtils';
import {getOriginalTransactionWithSplitInfo, hasTransactionBeenRejected} from '@libs/TransactionUtils';
import type {IOUType} from '@src/CONST';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -69,7 +70,7 @@
const [integrationsExportTemplates] = useOnyx(ONYXKEYS.NVP_INTEGRATION_SERVER_EXPORT_TEMPLATES, {canBeMissing: true});
const [csvExportLayouts] = useOnyx(ONYXKEYS.NVP_CSV_EXPORT_LAYOUTS, {canBeMissing: true});

const expensifyIcons = useMemoizedLazyExpensifyIcons(['Stopwatch', 'Trashcan', 'ArrowRight', 'Table', 'DocumentMerge', 'Export', 'ArrowCollapse', 'ArrowSplit'] as const);
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Stopwatch', 'Trashcan', 'ArrowRight', 'Table', 'DocumentMerge', 'Export', 'ArrowCollapse', 'ArrowSplit', 'ThumbsDown'] as const);
const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(selectedTransactionIDs);
const isReportArchived = useReportIsArchived(report?.reportID);
const {deleteTransactions} = useDeleteTransactions({report, reportActions, policy});
Expand Down Expand Up @@ -217,6 +218,20 @@
});
}

const hasNoRejectedTransaction = selectedTransactionIDs.every((id) => !hasTransactionBeenRejected(id));
Comment thread
stitesExpensify marked this conversation as resolved.
const canRejectTransactions =
selectedTransactionsList.length > 0 && isMoneyRequestReport && !!session?.email && !!report && canRejectReportAction(session.email, report, policy) && hasNoRejectedTransaction;
if (canRejectTransactions) {
options.push({
text: translate('search.bulkActions.reject'),
icon: expensifyIcons.ThumbsDown,
value: CONST.REPORT.SECONDARY_ACTIONS.REJECT,
onSelected: () => {
Comment thread
lakchote marked this conversation as resolved.
Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS.getRoute({reportID: report.reportID}));
},
});
}

// Gets the list of options for the export sub-menu
const getExportOptions = (): PopoverMenuItem[] => {
// We provide the basic and expense level export options by default
Expand Down Expand Up @@ -346,7 +361,7 @@
});
}
return options;
}, [

Check warning on line 364 in src/hooks/useSelectedTransactionsActions.ts

View workflow job for this annotation

GitHub Actions / ESLint check

React Hook useMemo has a missing dependency: 'session.email'. Either include it or remove the dependency array

Check warning on line 364 in src/hooks/useSelectedTransactionsActions.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useMemo has a missing dependency: 'session.email'. Either include it or remove the dependency array
selectedTransactionIDs,
report,
selectedTransactionsList,
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,7 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
[SCREENS.SEARCH.ROOT_VERIFY_ACCOUNT]: ROUTES.SEARCH_ROOT_VERIFY_ACCOUNT,
[SCREENS.SEARCH.MONEY_REQUEST_REPORT_VERIFY_ACCOUNT]: ROUTES.SEARCH_MONEY_REQUEST_REPORT_VERIFY_ACCOUNT.route,
[SCREENS.SEARCH.MONEY_REQUEST_REPORT_HOLD_TRANSACTIONS]: ROUTES.SEARCH_MONEY_REQUEST_REPORT_HOLD_TRANSACTIONS.route,
[SCREENS.SEARCH.MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS]: ROUTES.SEARCH_MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS.route,
[SCREENS.SEARCH.TRANSACTION_HOLD_REASON_RHP]: ROUTES.TRANSACTION_HOLD_REASON_RHP,
[SCREENS.SEARCH.SEARCH_REJECT_REASON_RHP]: ROUTES.SEARCH_REJECT_REASON_RHP,
[SCREENS.SEARCH.TRANSACTIONS_CHANGE_REPORT_SEARCH_RHP]: ROUTES.MOVE_TRANSACTIONS_SEARCH_RHP,
Expand Down
9 changes: 9 additions & 0 deletions src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
};

let deprecatedAllReports: OnyxCollection<Report> = {};
Onyx.connect({

Check warning on line 125 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -131,7 +131,7 @@
});

let deprecatedAllTransactionViolations: OnyxCollection<TransactionViolations> = {};
Onyx.connect({

Check warning on line 134 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
callback: (value) => (deprecatedAllTransactionViolations = value),
Expand Down Expand Up @@ -1149,6 +1149,14 @@
return deprecatedAllTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
}

/**
* Check if a transaction has been rejected
*/
function hasTransactionBeenRejected(transactionID: string): boolean {
Comment thread
stitesExpensify marked this conversation as resolved.
const transactionViolations = getTransactionViolationsOfTransaction(transactionID);
return transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.AUTO_REPORTED_REJECTED_EXPENSE);
}

/**
* Check if there is pending rter violation in transactionViolations.
*/
Expand Down Expand Up @@ -2336,6 +2344,7 @@
shouldShowViolation,
isUnreportedAndHasInvalidDistanceRateTransaction,
getTransactionViolationsOfTransaction,
hasTransactionBeenRejected,
isExpenseSplit,
getAttendeesListDisplayString,
isCorporateCardTransaction,
Expand Down
Loading
Loading