@@ -10,7 +10,7 @@ import CONST from '@src/CONST';
1010import type { TranslationPaths } from '@src/languages/types' ;
1111import ONYXKEYS from '@src/ONYXKEYS' ;
1212import ROUTES from '@src/ROUTES' ;
13- import type { Card , Locale , OnyxInputOrEntry , PrivatePersonalDetails } from '@src/types/onyx' ;
13+ import type { Card , Locale , OnyxInputOrEntry , OriginalMessageIOU , PrivatePersonalDetails } from '@src/types/onyx' ;
1414import type { JoinWorkspaceResolution , OriginalMessageChangeLog , OriginalMessageExportIntegration } from '@src/types/onyx/OriginalMessage' ;
1515import type { PolicyReportFieldType } from '@src/types/onyx/Policy' ;
1616import type Report from '@src/types/onyx/Report' ;
@@ -1185,6 +1185,37 @@ function isTagModificationAction(actionName: string): boolean {
11851185 ) ;
11861186}
11871187
1188+ /** Whether action has no linked report by design */
1189+ const isIOUActionTypeExcludedFromFiltering = ( type : OriginalMessageIOU [ 'type' ] | undefined ) =>
1190+ [ CONST . IOU . REPORT_ACTION_TYPE . SPLIT , CONST . IOU . REPORT_ACTION_TYPE . TRACK , CONST . IOU . REPORT_ACTION_TYPE . PAY ] . some ( ( actionType ) => actionType === type ) ;
1191+
1192+ /**
1193+ * Determines whether the given action is an IOU and, if a list of report transaction IDs is provided,
1194+ * whether it corresponds to one of those transactions. This covers a rare case where IOU report actions was
1195+ * not deleted or moved after the expense was removed from the report.
1196+ *
1197+ * For compatibility and to avoid using isMoneyRequest next to this function as it is checked here already:
1198+ * - If the action is not a money request and `defaultToFalseForNonIOU` is false (default), the result is true.
1199+ * - If no `reportTransactionIDs` are provided, the function returns true if the action is an IOU.
1200+ * - If `reportTransactionIDs` are provided, the function checks if the IOU transaction ID from the action matches any of them.
1201+ */
1202+ const isIOUActionMatchingTransactionList = (
1203+ action : ReportAction ,
1204+ reportTransactionIDs ?: string [ ] ,
1205+ defaultToFalseForNonIOU = false ,
1206+ ) : action is ReportAction < typeof CONST . REPORT . ACTIONS . TYPE . IOU > => {
1207+ if ( ! isMoneyRequestAction ( action ) ) {
1208+ return ! defaultToFalseForNonIOU ;
1209+ }
1210+
1211+ if ( isIOUActionTypeExcludedFromFiltering ( getOriginalMessage ( action ) ?. type ) || reportTransactionIDs === undefined ) {
1212+ return true ;
1213+ }
1214+
1215+ const { IOUTransactionID} = getOriginalMessage ( action ) ?? { } ;
1216+ return ! ! IOUTransactionID && reportTransactionIDs . includes ( IOUTransactionID ) ;
1217+ } ;
1218+
11881219/**
11891220 * Gets the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions.
11901221 * Returns a reportID if there is exactly one transaction thread for the report, and null otherwise.
@@ -1193,6 +1224,7 @@ function getOneTransactionThreadReportID(
11931224 reportID : string | undefined ,
11941225 reportActions : OnyxEntry < ReportActions > | ReportAction [ ] ,
11951226 isOffline : boolean | undefined = undefined ,
1227+ reportTransactionIDs ?: string [ ] ,
11961228) : string | undefined {
11971229 // If the report is not an IOU, Expense report, or Invoice, it shouldn't be treated as one-transaction report.
11981230 const report = allReports ?. [ `${ ONYXKEYS . COLLECTION . REPORT } ${ reportID } ` ] ;
@@ -1207,7 +1239,7 @@ function getOneTransactionThreadReportID(
12071239
12081240 const iouRequestActions = [ ] ;
12091241 for ( const action of reportActionsArray ) {
1210- if ( ! isMoneyRequestAction ( action ) ) {
1242+ if ( ! isIOUActionMatchingTransactionList ( action , reportTransactionIDs , true ) ) {
12111243 // eslint-disable-next-line no-continue
12121244 continue ;
12131245 }
@@ -2529,6 +2561,7 @@ export {
25292561 isForwardedAction ,
25302562 isWhisperActionTargetedToOthers ,
25312563 isTagModificationAction ,
2564+ isIOUActionMatchingTransactionList ,
25322565 isResolvedActionableWhisper ,
25332566 shouldHideNewMarker ,
25342567 shouldReportActionBeVisible ,
0 commit comments