diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 862b82edd25f..2ddb578c78c6 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -17,7 +17,7 @@ import useSelectedTransactionsActions from '@hooks/useSelectedTransactionsAction import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; -import {deleteAppReport, downloadReportPDF, exportReportToCSV, exportReportToPDF, exportToIntegration, markAsManuallyExported, openUnreportedExpense} from '@libs/actions/Report'; +import {deleteAppReport, downloadReportPDF, exportReportToCSV, exportReportToPDF, exportToIntegration, markAsManuallyExported, openReport, openUnreportedExpense} from '@libs/actions/Report'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; import {getThreadReportIDsForTransactions, getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -27,10 +27,11 @@ import {buildOptimisticNextStepForPreventSelfApprovalsEnabled} from '@libs/NextS import {isSecondaryActionAPaymentOption, selectPaymentType} from '@libs/PaymentUtils'; import type {KYCFlowEvent, TriggerKYCFlow} from '@libs/PaymentUtils'; import {getConnectedIntegration, getValidConnectedIntegration} from '@libs/PolicyUtils'; -import {getOriginalMessage, getReportAction, isMoneyRequestAction} from '@libs/ReportActionsUtils'; +import {getIOUActionForReportID, getOriginalMessage, getReportAction, isMoneyRequestAction} from '@libs/ReportActionsUtils'; import {getAllExpensesToHoldIfApplicable, getReportPrimaryAction} from '@libs/ReportPrimaryActionUtils'; import {getSecondaryExportReportActions, getSecondaryReportActions} from '@libs/ReportSecondaryActionUtils'; import { + buildTransactionThread, changeMoneyRequestHoldStatus, getArchiveReason, getIntegrationExportIcon, @@ -678,9 +679,14 @@ function MoneyReportHeader({ success text={translate('iou.reviewDuplicates')} onPress={() => { - const threadID = transactionThreadReportID ?? getFirstDuplicateThreadID(transactions, reportActions); + let threadID = transactionThreadReportID ?? getFirstDuplicateThreadID(transactions, reportActions); if (!threadID) { - return; + const duplicateTransaction = transactions.find((reportTransaction) => isDuplicate(reportTransaction)); + const transactionID = duplicateTransaction?.transactionID; + const iouAction = getIOUActionForReportID(moneyRequestReport?.reportID, transactionID); + const optimisticTransactionThread = buildTransactionThread(iouAction, moneyRequestReport); + threadID = optimisticTransactionThread.reportID; + openReport(threadID, undefined, session?.email ? [session?.email] : [], optimisticTransactionThread, iouAction?.reportActionID); } Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(threadID)); }} diff --git a/src/pages/TransactionDuplicate/Review.tsx b/src/pages/TransactionDuplicate/Review.tsx index 5562181671d6..a847cd3a0139 100644 --- a/src/pages/TransactionDuplicate/Review.tsx +++ b/src/pages/TransactionDuplicate/Review.tsx @@ -1,9 +1,11 @@ import {useRoute} from '@react-navigation/native'; -import React, {useMemo} from 'react'; +import React, {useEffect, useMemo} from 'react'; import {View} from 'react-native'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; +import ReportHeaderSkeletonView from '@components/ReportHeaderSkeletonView'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; @@ -11,6 +13,7 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; import useTransactionViolations from '@hooks/useTransactionViolations'; +import {openReport} from '@libs/actions/Report'; import {dismissDuplicateTransactionViolation} from '@libs/actions/Transaction'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; @@ -28,6 +31,7 @@ function TransactionDuplicateReview() { const route = useRoute>(); const currentPersonalDetails = useCurrentUserPersonalDetails(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`, {canBeMissing: true}); + const [reportMetadata] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${route.params.threadReportID}`, {canBeMissing: true}); const reportAction = getReportAction(report?.parentReportID, report?.parentReportActionID); const transactionID = getLinkedTransactionID(reportAction, report?.reportID) ?? undefined; const transactionViolations = useTransactionViolations(transactionID); @@ -56,9 +60,34 @@ function TransactionDuplicateReview() { const hasSettledOrApprovedTransaction = transactions?.some((transaction) => isSettled(transaction?.reportID) || isReportIDApproved(transaction?.reportID)); + useEffect(() => { + if (!route.params.threadReportID || report?.reportID) { + return; + } + openReport(route.params.threadReportID); + }, [report?.reportID, route.params.threadReportID]); + + const isLoadingPage = (!report?.reportID && reportMetadata?.isLoadingInitialReportActions !== false) || !reportAction?.reportActionID; + + // eslint-disable-next-line rulesdir/no-negated-variables + const shouldShowNotFound = !isLoadingPage && !transactionID; + + if (isLoadingPage) { + return ( + + + + {}} /> + + + + + ); + } + return ( - + Navigation.goBack(route.params.backTo)}