diff --git a/src/components/AttachmentModal.tsx b/src/components/AttachmentModal.tsx index 74ff19f21a46..4286c6c834eb 100644 --- a/src/components/AttachmentModal.tsx +++ b/src/components/AttachmentModal.tsx @@ -133,6 +133,8 @@ type AttachmentModalProps = { canEditReceipt?: boolean; + canDeleteReceipt?: boolean; + shouldDisableSendButton?: boolean; attachmentLink?: string; @@ -157,6 +159,7 @@ function AttachmentModal({ children, fallbackSource, canEditReceipt = false, + canDeleteReceipt = false, onModalClose = () => {}, isLoading = false, shouldShowNotFoundPage = false, @@ -447,7 +450,7 @@ function AttachmentModal({ } const hasOnlyEReceipt = hasEReceipt(transaction) && !hasReceiptSource(transaction); - if (!hasOnlyEReceipt && hasReceipt(transaction) && !isReceiptBeingScanned(transaction) && canEditReceipt && !hasMissingSmartscanFields(transaction)) { + if (!hasOnlyEReceipt && hasReceipt(transaction) && !isReceiptBeingScanned(transaction) && canDeleteReceipt && !hasMissingSmartscanFields(transaction)) { menuItems.push({ icon: Expensicons.Trashcan, text: translate('receipt.deleteReceipt'), diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 6ed05abcf134..c7c92ac79469 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3546,7 +3546,7 @@ function canEditMoneyRequest(reportAction: OnyxInputOrEntry, fieldToEdit: ValueOf): boolean { +function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry, fieldToEdit: ValueOf, isDeleteAction?: boolean): boolean { // A list of fields that cannot be edited by anyone, once an expense has been settled const restrictedFields: string[] = [ CONST.EDIT_REQUEST_FIELD.AMOUNT, @@ -3599,13 +3599,14 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.RECEIPT) { const isRequestor = currentUserAccountID === reportAction?.actorAccountID; - return ( - !isInvoiceReport(moneyRequestReport) && + return !isInvoiceReport(moneyRequestReport) && !isReceiptBeingScanned(transaction) && !isDistanceRequest(transaction) && !isPerDiemRequest(transaction) && - (isAdmin || isManager || isRequestor) - ); + (isAdmin || isManager || isRequestor) && + isDeleteAction + ? isRequestor + : true; } if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE) { diff --git a/src/pages/TransactionReceiptPage.tsx b/src/pages/TransactionReceiptPage.tsx index 497adef4ec1e..52ce46105e5d 100644 --- a/src/pages/TransactionReceiptPage.tsx +++ b/src/pages/TransactionReceiptPage.tsx @@ -1,16 +1,21 @@ import React, {useEffect} from 'react'; import {useOnyx} from 'react-native-onyx'; import AttachmentModal from '@components/AttachmentModal'; +import {openReport} from '@libs/actions/Report'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {AuthScreensParamList, RootStackParamList, State} from '@libs/Navigation/types'; -import * as ReceiptUtils from '@libs/ReceiptUtils'; -import * as ReportActionUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; -import * as TransactionUtils from '@libs/TransactionUtils'; +import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils'; +import {getReportAction, isTrackExpenseAction as isTrackExpenseReportReportActionsUtils} from '@libs/ReportActionsUtils'; +import { + canEditFieldOfMoneyRequest, + isMoneyRequestReport, + isOneTransactionThread as isOneTransactionThreadReportUtils, + isTrackExpenseReport as isTrackExpenseReportReportUtils, +} from '@libs/ReportUtils'; +import {hasEReceipt, hasReceiptSource} from '@libs/TransactionUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; import navigationRef from '@navigation/navigationRef'; -import * as ReportActions from '@userActions/Report'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -19,10 +24,10 @@ import type SCREENS from '@src/SCREENS'; type TransactionReceiptProps = PlatformStackScreenProps; function TransactionReceipt({route}: TransactionReceiptProps) { - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? '-1'}`); - const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${route.params.transactionID ?? '-1'}`); - const [reportMetadata = {isLoadingInitialReportActions: true}] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${route.params.reportID ?? '-1'}`); - const receiptURIs = ReceiptUtils.getThumbnailAndImageURIs(transaction); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? CONST.DEFAULT_NUMBER_ID}`); + const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${route.params.transactionID ?? CONST.DEFAULT_NUMBER_ID}`); + const [reportMetadata = {isLoadingInitialReportActions: true}] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${route.params.reportID ?? CONST.DEFAULT_NUMBER_ID}`); + const receiptURIs = getThumbnailAndImageURIs(transaction); const imageSource = tryResolveUrlFromApiRoot(receiptURIs.image ?? ''); @@ -30,16 +35,17 @@ function TransactionReceipt({route}: TransactionReceiptProps) { const readonly = route.params.readonly === 'true'; const isFromReviewDuplicates = route.params.isFromReviewDuplicates === 'true'; - const parentReportAction = ReportActionUtils.getReportAction(report?.parentReportID ?? '-1', report?.parentReportActionID ?? '-1'); - const canEditReceipt = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT); - const isEReceipt = transaction && !TransactionUtils.hasReceiptSource(transaction) && TransactionUtils.hasEReceipt(transaction); - const isTrackExpenseAction = ReportActionUtils.isTrackExpenseAction(parentReportAction); + const parentReportAction = getReportAction(report?.parentReportID, report?.parentReportActionID); + const canEditReceipt = canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT); + const canDeleteReceipt = canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT, true); + const isEReceipt = transaction && !hasReceiptSource(transaction) && hasEReceipt(transaction); + const isTrackExpenseAction = isTrackExpenseReportReportActionsUtils(parentReportAction); useEffect(() => { if (report && transaction) { return; } - ReportActions.openReport(route.params.reportID); + openReport(route.params.reportID); // I'm disabling the warning, as it expects to use exhaustive deps, even though we want this useEffect to run only on the first render. // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, []); @@ -52,17 +58,17 @@ function TransactionReceipt({route}: TransactionReceiptProps) { if (secondToLastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) { Navigation.dismissModal(); } else { - const isOneTransactionThread = ReportUtils.isOneTransactionThread(report?.reportID ?? '-1', report?.parentReportID ?? '-1', parentReportAction); + const isOneTransactionThread = isOneTransactionThreadReportUtils(report?.reportID, report?.parentReportID, parentReportAction); Navigation.dismissModal(isOneTransactionThread ? report?.parentReportID : report?.reportID); } }; - const moneyRequestReportID = ReportUtils.isMoneyRequestReport(report) ? report?.reportID : report?.parentReportID; - const isTrackExpenseReport = ReportUtils.isTrackExpenseReport(report); + const moneyRequestReportID = isMoneyRequestReport(report) ? report?.reportID : report?.parentReportID; + const isTrackExpenseReport = isTrackExpenseReportReportUtils(report); // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = - isTrackExpenseReport || transaction?.reportID === CONST.REPORT.SPLIT_REPORTID || isFromReviewDuplicates ? !transaction : (moneyRequestReportID ?? '-1') !== transaction?.reportID; + isTrackExpenseReport || transaction?.reportID === CONST.REPORT.SPLIT_REPORTID || isFromReviewDuplicates ? !transaction : moneyRequestReportID !== transaction?.reportID; return (