@@ -549,6 +549,11 @@ type OptimisticHoldReportExpenseActionID = {
549549 oldReportActionID : string ;
550550} ;
551551
552+ type MovedScanFailedTransaction = {
553+ transactionID : string ;
554+ optimisticReportActionID : string ;
555+ } ;
556+
552557function getHoldReportActionsAndTransactions (
553558 reportID : string | undefined ,
554559 iouReport ?: OnyxEntry < OnyxTypes . Report > ,
@@ -700,6 +705,7 @@ function getReportFromHoldRequestsOnyxData({
700705 optimisticCreatedReportForUnapprovedTransactionsActionID : string | undefined ;
701706 optimisticHoldReportExpenseActionIDs : OptimisticHoldReportExpenseActionID [ ] ;
702707 optimisticReportActionCopyIDs : OptimisticReportActionCopyIDs ;
708+ movedScanFailedTransactions : MovedScanFailedTransaction [ ] ;
703709 optimisticData : Array < OnyxUpdate < typeof ONYXKEYS . COLLECTION . REPORT | typeof ONYXKEYS . COLLECTION . REPORT_ACTIONS | typeof ONYXKEYS . COLLECTION . TRANSACTION > > ;
704710 successData : Array < OnyxUpdate < typeof ONYXKEYS . COLLECTION . REPORT | typeof ONYXKEYS . COLLECTION . REPORT_ACTIONS > > ;
705711 failureData : Array < OnyxUpdate < typeof ONYXKEYS . COLLECTION . REPORT | typeof ONYXKEYS . COLLECTION . REPORT_ACTIONS | typeof ONYXKEYS . COLLECTION . TRANSACTION > > ;
@@ -774,6 +780,7 @@ function getReportFromHoldRequestsOnyxData({
774780 const addHoldReportActionsSuccess : OnyxCollection < NullishDeep < OnyxTypes . ReportAction > > = { } ;
775781 const deleteHoldReportActions : Record < string , Pick < OnyxTypes . ReportAction , 'message' > > = { } ;
776782 const optimisticHoldReportExpenseActionIDs : OptimisticHoldReportExpenseActionID [ ] = [ ] ;
783+ const movedScanFailedTransactions : MovedScanFailedTransaction [ ] = [ ] ;
777784
778785 for ( const holdReportAction of holdReportActions ) {
779786 // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
@@ -803,6 +810,10 @@ function getReportFromHoldRequestsOnyxData({
803810
804811 optimisticHoldReportExpenseActionIDs . push ( { optimisticReportActionID : reportActionID , oldReportActionID : holdReportAction . reportActionID } ) ;
805812
813+ if ( shouldMoveScanFailedTransactions && originalMessage . IOUTransactionID ) {
814+ movedScanFailedTransactions . push ( { transactionID : originalMessage . IOUTransactionID , optimisticReportActionID : reportActionID } ) ;
815+ }
816+
806817 const heldReport = getReportOrDraftReport ( holdReportAction . childReportID ) ;
807818 if ( heldReport ) {
808819 updateHeldReports [ `${ ONYXKEYS . COLLECTION . REPORT } ${ heldReport . reportID } ` ] = {
@@ -1044,7 +1055,73 @@ function getReportFromHoldRequestsOnyxData({
10441055 optimisticHoldReportID : optimisticExpenseReport . reportID ,
10451056 optimisticHoldReportExpenseActionIDs,
10461057 optimisticReportActionCopyIDs,
1058+ movedScanFailedTransactions,
10471059 } ;
10481060}
10491061
1050- export { getReportFromHoldRequestsOnyxData , putOnHold , putTransactionsOnHold , unholdRequest } ;
1062+ function repointMovedScanFailedThread ( transactionID : string , optimisticReportID : string , optimisticReportActionID : string , realReportID : string ) {
1063+ // The backend's report actions for the moved expense may arrive after the transaction update, and this runs from the
1064+ // action layer where no view exists to subscribe with useOnyx, so connectWithoutView is the only way to wait for them.
1065+ const connection = Onyx . connectWithoutView ( {
1066+ key : `${ ONYXKEYS . COLLECTION . REPORT_ACTIONS } ${ realReportID } ` ,
1067+ callback : ( reportActions ) => {
1068+ const realAction = Object . values ( reportActions ?? { } ) . find (
1069+ ( reportAction ) => isMoneyRequestAction ( reportAction ) && getOriginalMessage ( reportAction ) ?. IOUTransactionID === transactionID ,
1070+ ) ;
1071+ if ( ! realAction ) {
1072+ return ;
1073+ }
1074+ Onyx . disconnect ( connection ) ;
1075+
1076+ const threadReport = Object . values ( getAllReports ( ) ?? { } ) . find (
1077+ ( report ) => report ?. parentReportActionID === optimisticReportActionID && report ?. parentReportID === optimisticReportID ,
1078+ ) ;
1079+ if ( threadReport ?. reportID ) {
1080+ Onyx . merge ( `${ ONYXKEYS . COLLECTION . REPORT } ${ threadReport . reportID } ` , {
1081+ parentReportID : realReportID ,
1082+ parentReportActionID : realAction . reportActionID ,
1083+ chatReportID : realReportID ,
1084+ } ) ;
1085+ if ( ! realAction . childReportID ) {
1086+ Onyx . merge ( `${ ONYXKEYS . COLLECTION . REPORT_ACTIONS } ${ realReportID } ` , {
1087+ [ realAction . reportActionID ] : { childReportID : threadReport . reportID } ,
1088+ } ) ;
1089+ }
1090+ }
1091+
1092+ if ( Navigation . getActiveRoute ( ) . includes ( optimisticReportID ) ) {
1093+ Navigation . setParams ( { reportID : realReportID } ) ;
1094+ }
1095+ } ,
1096+ } ) ;
1097+ }
1098+
1099+ function watchMovedScanFailedTransactions ( movedTransactions : MovedScanFailedTransaction [ ] , optimisticReportID : string ) {
1100+ for ( const { transactionID, optimisticReportActionID} of movedTransactions ) {
1101+ // The backend moves the expense into its own report instead of reusing optimisticReportID, and the only signal of
1102+ // the real report ID is the transaction's reportID changing. This runs from the action layer with no view to
1103+ // subscribe through, so connectWithoutView is required to observe that change.
1104+ let hasSeenOptimisticMove = false ;
1105+ const connection = Onyx . connectWithoutView ( {
1106+ key : `${ ONYXKEYS . COLLECTION . TRANSACTION } ${ transactionID } ` ,
1107+ callback : ( transaction ) => {
1108+ if ( ! transaction ) {
1109+ Onyx . disconnect ( connection ) ;
1110+ return ;
1111+ }
1112+ const currentReportID = transaction . reportID ;
1113+ if ( currentReportID === optimisticReportID ) {
1114+ hasSeenOptimisticMove = true ;
1115+ return ;
1116+ }
1117+ if ( ! hasSeenOptimisticMove || ! currentReportID ) {
1118+ return ;
1119+ }
1120+ Onyx . disconnect ( connection ) ;
1121+ repointMovedScanFailedThread ( transactionID , optimisticReportID , optimisticReportActionID , currentReportID ) ;
1122+ } ,
1123+ } ) ;
1124+ }
1125+ }
1126+
1127+ export { getReportFromHoldRequestsOnyxData , putOnHold , putTransactionsOnHold , unholdRequest , watchMovedScanFailedTransactions } ;
0 commit comments