diff --git a/src/components/Search.tsx b/src/components/Search.tsx
index 28c3ae5fdc4b..3d295e72c09e 100644
--- a/src/components/Search.tsx
+++ b/src/components/Search.tsx
@@ -8,6 +8,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import * as SearchActions from '@libs/actions/Search';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import Log from '@libs/Log';
+import * as ReportUtils from '@libs/ReportUtils';
import * as SearchUtils from '@libs/SearchUtils';
import type {SearchColumnType, SortOrder} from '@libs/SearchUtils';
import Navigation from '@navigation/Navigation';
@@ -34,9 +35,9 @@ type SearchProps = {
const sortableSearchTabs: SearchQuery[] = [CONST.TAB_SEARCH.ALL];
-function isReportListItemType(item: TransactionListItemType | ReportListItemType): item is ReportListItemType {
- const reportListItem = item as ReportListItemType;
- return reportListItem.transactions !== undefined;
+function isTransactionListItemType(item: TransactionListItemType | ReportListItemType): item is TransactionListItemType {
+ const transactionListItem = item as TransactionListItemType;
+ return transactionListItem.transactionID !== undefined;
}
function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) {
@@ -76,11 +77,19 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) {
return ;
}
- const openReport = (reportID?: string) => {
+ const openReport = (item: TransactionListItemType | ReportListItemType) => {
+ let reportID = isTransactionListItemType(item) ? item.transactionThreadReportID : item.reportID;
+
if (!reportID) {
return;
}
+ // If we're trying to open a legacy transaction without a transaction thread, let's create the thread and navigate the user
+ if (isTransactionListItemType(item) && reportID === '0' && item.moneyRequestReportActionID) {
+ reportID = ReportUtils.generateReportID();
+ SearchActions.createTransactionThread(hash, item.transactionID, reportID, item.moneyRequestReportActionID);
+ }
+
Navigation.navigate(ROUTES.SEARCH_REPORT.getRoute(query, reportID));
};
@@ -137,10 +146,7 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) {
updateCellsBatchingPeriod={200}
ListItem={ListItem}
sections={[{data: sortedData, isDisabled: false}]}
- onSelectRow={(item) => {
- const reportID = isReportListItemType(item) ? item.reportID : item.transactionThreadReportID;
- openReport(reportID);
- }}
+ onSelectRow={(item) => openReport(item)}
shouldDebounceRowSelect
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts
index 43f3e2697e8a..bf94de9c52b2 100644
--- a/src/libs/actions/Search.ts
+++ b/src/libs/actions/Search.ts
@@ -4,6 +4,16 @@ import * as API from '@libs/API';
import type {SearchParams} from '@libs/API/parameters';
import {READ_COMMANDS} from '@libs/API/types';
import ONYXKEYS from '@src/ONYXKEYS';
+import type {SearchTransaction} from '@src/types/onyx/SearchResults';
+import * as Report from './Report';
+
+let currentUserEmail: string;
+Onyx.connect({
+ key: ONYXKEYS.SESSION,
+ callback: (val) => {
+ currentUserEmail = val?.email ?? '';
+ },
+});
function search({hash, query, policyIDs, offset, sortBy, sortOrder}: SearchParams) {
const optimisticData: OnyxUpdate[] = [
@@ -32,7 +42,23 @@ function search({hash, query, policyIDs, offset, sortBy, sortOrder}: SearchParam
API.read(READ_COMMANDS.SEARCH, {hash, query, offset, policyIDs, sortBy, sortOrder}, {optimisticData, finallyData});
}
-export {
- // eslint-disable-next-line import/prefer-default-export
- search,
-};
+
+/**
+ * It's possible that we return legacy transactions that don't have a transaction thread created yet.
+ * In that case, when users select the search result row, we need to create the transaction thread on the fly and update the search result with the new transactionThreadReport
+ */
+function createTransactionThread(hash: number, transactionID: string, reportID: string, moneyRequestReportActionID: string) {
+ Report.openReport(reportID, '', [currentUserEmail], {}, moneyRequestReportActionID);
+
+ const onyxUpdate: Record>> = {
+ data: {
+ [`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: {
+ transactionThreadReportID: reportID,
+ },
+ },
+ };
+
+ Onyx.merge(`${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`, onyxUpdate);
+}
+
+export {search, createTransactionThread};
diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts
index c7d63e95fd3d..5189a125db9c 100644
--- a/src/types/onyx/SearchResults.ts
+++ b/src/types/onyx/SearchResults.ts
@@ -151,6 +151,9 @@ type SearchTransaction = {
/** The modified MCC Group associated with the transaction */
modifiedMCCGroup?: ValueOf;
+
+ /** The ID of the money request reportAction associated with the transaction */
+ moneyRequestReportActionID?: string;
};
type SearchAccountDetails = Partial;