From b34ff54e949b5bca3a67c8779572871692b3c55f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 2 Oct 2025 17:00:12 +0200 Subject: [PATCH 01/21] chore: remove the check --- .../ReportActionItem/MoneyRequestView.tsx | 20 ++++++------------- src/libs/Permissions.ts | 8 -------- src/libs/ReportUtils.ts | 2 +- src/libs/TransactionUtils/index.ts | 5 ----- .../request/step/IOURequestStepCategory.tsx | 12 ++--------- .../iou/request/step/IOURequestStepTag.tsx | 11 ++-------- .../step/IOURequestStepTaxRatePage.tsx | 12 ++--------- 7 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 3b1ad6aae3c1b..cd0fe680045f7 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -145,14 +145,9 @@ function MoneyRequestView({ const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(linkedTransactionID)}`, {canBeMissing: true}); const isExpenseUnreported = isExpenseUnreportedTransactionUtils(updatedTransaction ?? transaction); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, { - canBeMissing: true, - selector: activePolicySelector, - }); // If the expense is unreported the policy should be the user's default policy, otherwise it should be the policy the expense was made for - const policy = isExpenseUnreported ? activePolicy : expensePolicy; - const policyID = isExpenseUnreported ? activePolicy?.id : report?.policyID; + const policy = expensePolicy; + const policyID = report?.policyID; const allPolicyCategories = usePolicyCategories(); const policyCategories = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`]; @@ -245,9 +240,6 @@ function MoneyRequestView({ // A flag for verifying that the current report is a sub-report of a expense chat // if the policy of the report is either Collect or Control, then this report must be tied to expense chat const isPolicyExpenseChat = isReportInGroupPolicy(report); - - const shouldShowPolicySpecificFields = isPolicyExpenseChat || isExpenseUnreported; - const policyTagLists = useMemo(() => getTagLists(policyTagList), [policyTagList]); const iouType = useMemo(() => { @@ -267,11 +259,11 @@ function MoneyRequestView({ // Flags for showing categories and tags // transactionCategory can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const shouldShowCategory = (isPolicyExpenseChat && (categoryForDisplay || hasEnabledOptions(policyCategories ?? {}))) || isExpenseUnreported; + const shouldShowCategory = isPolicyExpenseChat && (categoryForDisplay || hasEnabledOptions(policyCategories ?? {})); // transactionTag can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const shouldShowTag = shouldShowPolicySpecificFields && (transactionTag || hasEnabledTags(policyTagLists)); - const shouldShowBillable = shouldShowPolicySpecificFields && (!!transactionBillable || !(policy?.disabledFields?.defaultBillable ?? true) || !!updatedTransaction?.billable); + const shouldShowTag = isPolicyExpenseChat && (transactionTag || hasEnabledTags(policyTagLists)); + const shouldShowBillable = isPolicyExpenseChat && (!!transactionBillable || !(policy?.disabledFields?.defaultBillable ?? true) || !!updatedTransaction?.billable); const isCurrentTransactionReimbursableDifferentFromPolicyDefault = policy?.defaultReimbursable !== undefined && !!(updatedTransaction?.reimbursable ?? transactionReimbursable) !== policy.defaultReimbursable; const shouldShowReimbursable = @@ -279,7 +271,7 @@ function MoneyRequestView({ const canEditReimbursable = isEditable && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REIMBURSABLE, undefined, isChatReportArchived); const shouldShowAttendees = useMemo(() => shouldShowAttendeesTransactionUtils(iouType, policy), [iouType, policy]); - const shouldShowTax = isTaxTrackingEnabled(shouldShowPolicySpecificFields, policy, isDistanceRequest, isPerDiemRequest); + const shouldShowTax = isTaxTrackingEnabled(isPolicyExpenseChat, policy, isDistanceRequest, isPerDiemRequest); const tripID = getTripIDFromTransactionParentReportID(parentReport?.parentReportID); const shouldShowViewTripDetails = hasReservationList(transaction) && !!tripID; diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index bff77bcb9538c..434b8647e9739 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -15,13 +15,6 @@ function canUseLinkPreviews(): boolean { return false; } -/** - * Temporary check for Unreported Expense Project - change to true for testing - */ -function canUseUnreportedExpense(): boolean { - return false; -} - function isBetaEnabled(beta: Beta, betas: OnyxEntry, betaConfiguration?: OnyxEntry): boolean { const hasAllBetasEnabled = canUseAllBetas(betas); const isFeatureEnabled = !!betas?.includes(beta); @@ -38,5 +31,4 @@ function isBetaEnabled(beta: Beta, betas: OnyxEntry, betaConfiguration?: export default { canUseLinkPreviews, isBetaEnabled, - canUseUnreportedExpense, }; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 2d00e85b489e9..83f4c2313e871 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4381,7 +4381,7 @@ function canEditFieldOfMoneyRequest( const isUserWorkspaceMember = getActivePolicies(allPolicies ?? {}, currentUserEmail).filter(userPolicy => isPaidGroupPolicyPolicyUtils(userPolicy)).length; - if (isUnreportedExpense && isSearchPageOption && isUserWorkspaceMember) { + if (isUnreportedExpense && isUserWorkspaceMember) { return true; } diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index caf0040b38a6a..aa29d779cd1f4 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -1950,12 +1950,7 @@ function createUnreportedExpenseSections(transactions: Array Date: Thu, 2 Oct 2025 18:12:20 +0200 Subject: [PATCH 02/21] feat: create report button for workspace expenses --- .../ReportActionItem/MoneyRequestView.tsx | 3 --- src/libs/ReportUtils.ts | 2 +- src/pages/NewReportWorkspaceSelectionPage.tsx | 19 +++++++++++++++---- .../step/IOURequestEditReportCommon.tsx | 2 +- .../iou/request/step/IOURequestStepReport.tsx | 18 +++++++++++++++++- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index cd0fe680045f7..6a53fed7d9fd1 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -1,4 +1,3 @@ -import {activePolicySelector} from '@selectors/Policy'; import {Str} from 'expensify-common'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; @@ -66,7 +65,6 @@ import { isCardTransaction as isCardTransactionTransactionUtils, isDistanceRequest as isDistanceRequestTransactionUtils, isExpenseSplit, - isExpenseUnreported as isExpenseUnreportedTransactionUtils, isManualDistanceRequest as isManualDistanceRequestTransactionUtils, isPerDiemRequest as isPerDiemRequestTransactionUtils, isScanning, @@ -143,7 +141,6 @@ function MoneyRequestView({ return originalMessage?.IOUTransactionID; }, [parentReportAction]); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(linkedTransactionID)}`, {canBeMissing: true}); - const isExpenseUnreported = isExpenseUnreportedTransactionUtils(updatedTransaction ?? transaction); // If the expense is unreported the policy should be the user's default policy, otherwise it should be the policy the expense was made for const policy = expensePolicy; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 83f4c2313e871..2d00e85b489e9 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4381,7 +4381,7 @@ function canEditFieldOfMoneyRequest( const isUserWorkspaceMember = getActivePolicies(allPolicies ?? {}, currentUserEmail).filter(userPolicy => isPaidGroupPolicyPolicyUtils(userPolicy)).length; - if (isUnreportedExpense && isUserWorkspaceMember) { + if (isUnreportedExpense && isSearchPageOption && isUserWorkspaceMember) { return true; } diff --git a/src/pages/NewReportWorkspaceSelectionPage.tsx b/src/pages/NewReportWorkspaceSelectionPage.tsx index f2792b68354bf..4b5c45e6a1cdf 100644 --- a/src/pages/NewReportWorkspaceSelectionPage.tsx +++ b/src/pages/NewReportWorkspaceSelectionPage.tsx @@ -43,7 +43,7 @@ type NewReportWorkspaceSelectionPageProps = PlatformStackScreenProps(() => { diff --git a/src/pages/iou/request/step/IOURequestEditReportCommon.tsx b/src/pages/iou/request/step/IOURequestEditReportCommon.tsx index b85ed50b75431..db2e4008148eb 100644 --- a/src/pages/iou/request/step/IOURequestEditReportCommon.tsx +++ b/src/pages/iou/request/step/IOURequestEditReportCommon.tsx @@ -152,7 +152,7 @@ function IOURequestEditReportCommon({ const headerMessage = useMemo(() => (searchValue && !reportOptions.length ? translate('common.noResultsFound') : ''), [searchValue, reportOptions, translate]); const createReportOption = useMemo(() => { - if (!createReport || isUnreported === false) { + if (!createReport || isUnreported) { return undefined; } diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index 5fb9ef76b2032..5947674c6a5bb 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -3,8 +3,11 @@ import {InteractionManager} from 'react-native'; import {useSession} from '@components/OnyxListItemProvider'; import {useSearchContext} from '@components/Search/SearchContext'; import type {ListItem} from '@components/SelectionListWithSections/types'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useOnyx from '@hooks/useOnyx'; +import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses'; import useShowNotFoundPageInIOUStep from '@hooks/useShowNotFoundPageInIOUStep'; +import {createNewReport} from '@libs/actions/Report'; import {changeTransactionsReport, setTransactionReport} from '@libs/actions/Transaction'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; @@ -37,7 +40,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const outstandingReportID = isPolicyExpenseChat(participantReport) ? participantReport?.iouReportID : participantReportID; const selectedReportID = shouldUseTransactionReport ? transactionReport?.reportID : outstandingReportID; const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); - const {removeTransaction} = useSearchContext(); + const {removeTransaction, setSelectedTransactions} = useSearchContext(); const reportOrDraftReport = getReportOrDraftReport(reportIDFromRoute); const isEditing = action === CONST.IOU.ACTION.EDIT; const isCreateReport = action === CONST.IOU.ACTION.CREATE; @@ -45,6 +48,8 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const [allBetas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const isASAPSubmitBetaEnabled = Permissions.isBetaEnabled(CONST.BETAS.ASAP_SUBMIT, allBetas); const session = useSession(); + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); const handleGoBack = () => { if (isEditing) { @@ -160,6 +165,16 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = useShowNotFoundPageInIOUStep(action, iouType, reportActionID, reportOrDraftReport, transaction); + const createReport = () => { + if (shouldSelectPolicy) { + setSelectedTransactions([transactionID]); + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true)); + return; + } + const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + handleRegularReportSelection({value: createdReportID}); + }; + return ( ); } From 6f5af51fa7164d64a1881d4e3043604de6d10953 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 3 Oct 2025 12:11:22 +0200 Subject: [PATCH 03/21] feat: navigate to new report --- src/pages/iou/request/step/IOURequestStepReport.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index 5947674c6a5bb..f81f0c7d42d55 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -173,6 +173,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { } const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); handleRegularReportSelection({value: createdReportID}); + Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID})); }; return ( From 5659f17d2533b3c076c3f5be79ab3f793a0c9fb7 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 6 Oct 2025 10:24:24 +0200 Subject: [PATCH 04/21] fix: eslint --- src/libs/TransactionUtils/index.ts | 1 - src/pages/iou/request/step/IOURequestEditReportCommon.tsx | 2 +- src/pages/iou/request/step/IOURequestStepTag.tsx | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 0fc33a8e257dc..ed879650fb830 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -17,7 +17,6 @@ import {toLocaleDigit} from '@libs/LocaleDigitUtils'; import {translateLocal} from '@libs/Localize'; import Log from '@libs/Log'; import {rand64, roundToTwoDecimalPlaces} from '@libs/NumberUtils'; -import Permissions from '@libs/Permissions'; import {getPersonalDetailsByIDs} from '@libs/PersonalDetailsUtils'; import { getCommaSeparatedTagNameWithSanitizedColons, diff --git a/src/pages/iou/request/step/IOURequestEditReportCommon.tsx b/src/pages/iou/request/step/IOURequestEditReportCommon.tsx index db2e4008148eb..f1ae4bb22d6d8 100644 --- a/src/pages/iou/request/step/IOURequestEditReportCommon.tsx +++ b/src/pages/iou/request/step/IOURequestEditReportCommon.tsx @@ -185,7 +185,7 @@ function IOURequestEditReportCommon({ const isSubmitter = isReportOwner(selectedReport); // If the report is Open, then only submitters, admins can move expenses return isOpen && !isAdmin && !isSubmitter; - }, [createReport, selectedReport, reportPolicy, shouldShowNotFoundPageFromProps]); + }, [createReport, expenseReports.length, shouldShowNotFoundPageFromProps, selectedReport, reportPolicy]); return ( Date: Mon, 6 Oct 2025 15:38:11 +0200 Subject: [PATCH 05/21] fix: create report option on editing inside the report --- .../iou/request/step/IOURequestEditReport.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index 6a68c8ba1167a..a370bd2756144 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -2,13 +2,17 @@ import React from 'react'; import {useSession} from '@components/OnyxListItemProvider'; import {useSearchContext} from '@components/Search/SearchContext'; import type {ListItem} from '@components/SelectionListWithSections/types'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useOnyx from '@hooks/useOnyx'; +import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; import {changeTransactionsReport} from '@libs/actions/Transaction'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; +import {createNewReport} from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import IOURequestEditReportCommon from './IOURequestEditReportCommon'; import withWritableReportOrNotFound from './withWritableReportOrNotFound'; @@ -33,6 +37,8 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { const session = useSession(); const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); const [allPolicyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}`, {canBeMissing: true}); + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); const selectReport = (item: TransactionGroupListItem) => { if (selectedTransactionIDs.length === 0 || item.value === reportID) { @@ -67,6 +73,16 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { Navigation.dismissModal(); }; + const createReport = () => { + if (shouldSelectPolicy) { + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true)); + return; + } + const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + selectReport({value: createdReportID}); + Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID})); + }; + return ( ); } From 7e4a8f9882da3a4cd18155dda528d37daf0c8ca7 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 6 Oct 2025 15:52:32 +0200 Subject: [PATCH 06/21] fix: navigation --- src/pages/iou/request/step/IOURequestStepReport.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index ae02949662fac..ef1470643b763 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -51,6 +51,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const session = useSession(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); + console.log(action); const handleGoBack = () => { if (isEditing) { @@ -176,7 +177,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { } const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); handleRegularReportSelection({value: createdReportID}); - Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID})); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(createdReportID)); }; return ( @@ -190,7 +191,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { isEditing={isEditing} isUnreported={isUnreported} shouldShowNotFoundPage={shouldShowNotFoundPage} - createReport={createReport} + createReport={action === CONST.IOU.ACTION.EDIT ? createReport : undefined} /> ); } From 68a9e9f4278c5a87fc4317a62b7a1668f74155f3 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 6 Oct 2025 16:10:25 +0200 Subject: [PATCH 07/21] fix: handle back navigation --- src/ROUTES.ts | 7 ++++++- src/libs/Navigation/types.ts | 1 + src/pages/NewReportWorkspaceSelectionPage.tsx | 4 ++-- src/pages/iou/request/step/IOURequestEditReport.tsx | 7 ++++--- src/pages/iou/request/step/IOURequestStepReport.tsx | 7 ++++--- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 8df6f8c4c7de6..ffed189a69de9 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -438,7 +438,12 @@ const ROUTES = { NEW_REPORT_WORKSPACE_SELECTION: { route: 'new-report-workspace-selection', - getRoute: (isMovingExpenses?: boolean) => `new-report-workspace-selection${isMovingExpenses ? '?isMovingExpenses=true' : ''}` as const, + getRoute: (isMovingExpenses?: boolean, backTo?: string) => { + const baseRoute = `new-report-workspace-selection${isMovingExpenses ? '?isMovingExpenses=true' : ''}` as const; + + // eslint-disable-next-line no-restricted-syntax -- Legacy route generation + return getUrlWithBackToParam(baseRoute, backTo); + }, }, REPORT: 'r', REPORT_WITH_ID: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 6997cf171388b..142162a6ff2d3 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1206,6 +1206,7 @@ type ProfileNavigatorParamList = { type NewReportWorkspaceSelectionNavigatorParamList = { [SCREENS.NEW_REPORT_WORKSPACE_SELECTION.ROOT]: { isMovingExpenses?: boolean; + backTo?: Routes; }; }; diff --git a/src/pages/NewReportWorkspaceSelectionPage.tsx b/src/pages/NewReportWorkspaceSelectionPage.tsx index a87ef9fbf4938..b5de976606e3a 100644 --- a/src/pages/NewReportWorkspaceSelectionPage.tsx +++ b/src/pages/NewReportWorkspaceSelectionPage.tsx @@ -42,7 +42,7 @@ type WorkspaceListItem = { type NewReportWorkspaceSelectionPageProps = PlatformStackScreenProps; function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPageProps) { - const {isMovingExpenses} = route.params ?? {}; + const {isMovingExpenses, backTo} = route.params ?? {}; const {isOffline} = useNetwork(); const {selectedTransactions, selectedTransactionIDs, clearSelectedTransactions} = useSearchContext(); const styles = useThemeStyles(); @@ -99,7 +99,7 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag ); clearSelectedTransactions(); Navigation.dismissModal(); - Navigation.goBack(ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); + Navigation.goBack(backTo ?? ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); return; } navigateToNewReport(optimisticReportID); diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index a370bd2756144..4b681816e9e3d 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -74,13 +74,14 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { }; const createReport = () => { + const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + const backToRoute = ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID}) if (shouldSelectPolicy) { - Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true)); + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); return; } - const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); selectReport({value: createdReportID}); - Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID})); + Navigation.navigate(backToRoute, {forceReplace: true}); }; return ( diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index ef1470643b763..77237227b018e 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -170,14 +170,15 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const shouldShowNotFoundPage = useShowNotFoundPageInIOUStep(action, iouType, reportActionID, reportOrDraftReport, transaction); const createReport = () => { + const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + const backToRoute = ROUTES.REPORT_WITH_ID.getRoute(createdReportID); if (shouldSelectPolicy) { setSelectedTransactions([transactionID]); - Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true)); + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); return; } - const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); handleRegularReportSelection({value: createdReportID}); - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(createdReportID)); + Navigation.navigate(backToRoute, {forceReplace: true}); }; return ( From 95c459f1560689c50c8f631c2be3660f260a41ef Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 6 Oct 2025 17:12:27 +0200 Subject: [PATCH 08/21] fix: prettier --- src/ROUTES.ts | 2 +- src/pages/iou/request/step/IOURequestEditReport.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index ffed189a69de9..179d14f613e81 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -440,7 +440,7 @@ const ROUTES = { route: 'new-report-workspace-selection', getRoute: (isMovingExpenses?: boolean, backTo?: string) => { const baseRoute = `new-report-workspace-selection${isMovingExpenses ? '?isMovingExpenses=true' : ''}` as const; - + // eslint-disable-next-line no-restricted-syntax -- Legacy route generation return getUrlWithBackToParam(baseRoute, backTo); }, diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index 4b681816e9e3d..85d13fecb95e2 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -75,7 +75,7 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { const createReport = () => { const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); - const backToRoute = ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID}) + const backToRoute = ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID}); if (shouldSelectPolicy) { Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); return; From 6e316a21bcfd95b9da1f9b875e0fe7ecd426cbfb Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 12:48:01 +0200 Subject: [PATCH 09/21] fix: add missing params --- src/pages/Search/SearchTransactionsChangeReport.tsx | 2 +- src/pages/iou/request/step/IOURequestEditReport.tsx | 5 ++++- src/pages/iou/request/step/IOURequestStepReport.tsx | 7 ++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pages/Search/SearchTransactionsChangeReport.tsx b/src/pages/Search/SearchTransactionsChangeReport.tsx index bf257e8cdea3d..4105a73cd6f09 100644 --- a/src/pages/Search/SearchTransactionsChangeReport.tsx +++ b/src/pages/Search/SearchTransactionsChangeReport.tsx @@ -27,10 +27,10 @@ function SearchTransactionsChangeReport() { const [allReportNextSteps] = useOnyx(ONYXKEYS.COLLECTION.NEXT_STEP, {canBeMissing: true}); const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); const [allPolicyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}`, {canBeMissing: true}); - const [allBetas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); const hasViolations = hasViolationsReportUtils(undefined, transactionViolations); + const [allBetas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const isASAPSubmitBetaEnabled = Permissions.isBetaEnabled(CONST.BETAS.ASAP_SUBMIT, allBetas); const session = useSession(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index 34a5236911f42..ac1f57489b610 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -7,6 +7,7 @@ import useOnyx from '@hooks/useOnyx'; import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; import {changeTransactionsReport} from '@libs/actions/Transaction'; +import {hasViolations as hasViolationsReportUtils} from '@libs/ReportUtils'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; import {createNewReport} from '@userActions/Report'; @@ -39,6 +40,8 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { const [allPolicyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}`, {canBeMissing: true}); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); + const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); + const hasViolations = hasViolationsReportUtils(undefined, transactionViolations); const selectReport = (item: TransactionGroupListItem) => { if (selectedTransactionIDs.length === 0 || item.value === reportID) { @@ -74,7 +77,7 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { }; const createReport = () => { - const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); const backToRoute = ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID}); if (shouldSelectPolicy) { Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index b673159da1f47..1ea71eb728a44 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -11,7 +11,7 @@ import {createNewReport} from '@libs/actions/Report'; import {changeTransactionsReport, setTransactionReport} from '@libs/actions/Transaction'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; -import {getReportOrDraftReport, isPolicyExpenseChat, isReportOutstanding} from '@libs/ReportUtils'; +import {getReportOrDraftReport, hasViolations as hasViolationsReportUtils, isPolicyExpenseChat, isReportOutstanding} from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -51,7 +51,8 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const session = useSession(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {policyForMovingExpensesID, shouldSelectPolicy} = usePolicyForMovingExpenses(); - console.log(action); + const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); + const hasViolations = hasViolationsReportUtils(undefined, transactionViolations); const handleGoBack = () => { if (isEditing) { @@ -170,7 +171,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const shouldShowNotFoundPage = useShowNotFoundPageInIOUStep(action, iouType, reportActionID, reportOrDraftReport, transaction); const createReport = () => { - const createdReportID = createNewReport(currentUserPersonalDetails, policyForMovingExpensesID); + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); const backToRoute = ROUTES.REPORT_WITH_ID.getRoute(createdReportID); if (shouldSelectPolicy) { setSelectedTransactions([transactionID]); From 9b393620f9e9ad62a552e6a83c28ea6c2081e713 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 12:49:10 +0200 Subject: [PATCH 10/21] fix: do not navigate after creating new report --- src/pages/iou/request/step/IOURequestEditReport.tsx | 1 - src/pages/iou/request/step/IOURequestStepReport.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index ac1f57489b610..9118674a75e54 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -84,7 +84,6 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { return; } selectReport({value: createdReportID}); - Navigation.navigate(backToRoute, {forceReplace: true}); }; return ( diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index 1ea71eb728a44..1852aae73daed 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -179,7 +179,6 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { return; } handleRegularReportSelection({value: createdReportID}); - Navigation.navigate(backToRoute, {forceReplace: true}); }; return ( From 6ef8ab6648b8c583f750d3ffabbd4d6cc35b5f9b Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 14:07:27 +0200 Subject: [PATCH 11/21] fix: prettier --- src/pages/iou/request/step/IOURequestEditReport.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index 9118674a75e54..423c50e0790d0 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -7,9 +7,9 @@ import useOnyx from '@hooks/useOnyx'; import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; import {changeTransactionsReport} from '@libs/actions/Transaction'; -import {hasViolations as hasViolationsReportUtils} from '@libs/ReportUtils'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; +import {hasViolations as hasViolationsReportUtils} from '@libs/ReportUtils'; import {createNewReport} from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; From ee256a6e51a75e20f50dd846aca1dd8d05bee430 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 17:19:27 +0200 Subject: [PATCH 12/21] fix: do not create report --- src/pages/iou/request/step/IOURequestEditReport.tsx | 5 ++--- src/pages/iou/request/step/IOURequestStepReport.tsx | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestEditReport.tsx b/src/pages/iou/request/step/IOURequestEditReport.tsx index 423c50e0790d0..94de2ddeb6d07 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -77,12 +77,11 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { }; const createReport = () => { - const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); - const backToRoute = ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID: createdReportID}); if (shouldSelectPolicy) { - Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backTo)); return; } + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); selectReport({value: createdReportID}); }; diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index 1852aae73daed..594e8d52df3c0 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -171,13 +171,12 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const shouldShowNotFoundPage = useShowNotFoundPageInIOUStep(action, iouType, reportActionID, reportOrDraftReport, transaction); const createReport = () => { - const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); - const backToRoute = ROUTES.REPORT_WITH_ID.getRoute(createdReportID); if (shouldSelectPolicy) { setSelectedTransactions([transactionID]); - Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backToRoute)); + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backTo)); return; } + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); handleRegularReportSelection({value: createdReportID}); }; From 8b88e036d53a7f1bfd0e6ab1e64b9a7327718a9c Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 17:29:47 +0200 Subject: [PATCH 13/21] fix: navigation issuea and selected checkboxes --- .../ReportActionItem/MoneyRequestView.tsx | 9 ++++++++- src/hooks/useSelectedTransactionsActions.ts | 3 ++- src/pages/NewReportWorkspaceSelectionPage.tsx | 13 +++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index f26e562cdbd5c..c15c6cb67876c 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -129,6 +129,7 @@ function MoneyRequestView({ const {isBetaEnabled} = usePermissions(); const {translate, toLocaleDigit} = useLocalize(); const {getReportRHPActiveRoute} = useActiveRoute(); + const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH, {canBeMissing: true}); const parentReportID = report?.parentReportID; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; @@ -846,7 +847,13 @@ function MoneyRequestView({ return; } Navigation.navigate( - ROUTES.MONEY_REQUEST_STEP_REPORT.getRoute(CONST.IOU.ACTION.EDIT, iouType, transaction?.transactionID, report.reportID, getReportRHPActiveRoute()), + ROUTES.MONEY_REQUEST_STEP_REPORT.getRoute( + CONST.IOU.ACTION.EDIT, + iouType, + transaction?.transactionID, + report.reportID, + getReportRHPActiveRoute() ?? lastVisitedPath, + ), ); }} interactive={canEditReport} diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index 6838967311966..a6478f93e36e0 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -59,6 +59,7 @@ function useSelectedTransactionsActions({ const {selectedTransactionIDs, clearSelectedTransactions} = useSearchContext(); const [allTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: false}); const [outstandingReportsByPolicyID] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID, {canBeMissing: true}); + const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH, {canBeMissing: true}); const [integrationsExportTemplates] = useOnyx(ONYXKEYS.NVP_INTEGRATION_SERVER_EXPORT_TEMPLATES, {canBeMissing: true}); const [csvExportLayouts] = useOnyx(ONYXKEYS.NVP_CSV_EXPORT_LAYOUTS, {canBeMissing: true}); @@ -252,7 +253,7 @@ function useSelectedTransactionsActions({ value: MOVE, onSelected: () => { const shouldTurnOffSelectionMode = allTransactionsLength - selectedTransactionIDs.length <= 1; - const route = ROUTES.MONEY_REQUEST_EDIT_REPORT.getRoute(CONST.IOU.ACTION.EDIT, iouType, report?.reportID, shouldTurnOffSelectionMode); + const route = ROUTES.MONEY_REQUEST_EDIT_REPORT.getRoute(CONST.IOU.ACTION.EDIT, iouType, report?.reportID, shouldTurnOffSelectionMode, lastVisitedPath); Navigation.navigate(route); }, }); diff --git a/src/pages/NewReportWorkspaceSelectionPage.tsx b/src/pages/NewReportWorkspaceSelectionPage.tsx index 0a4376bdec381..5a646f83a7abf 100644 --- a/src/pages/NewReportWorkspaceSelectionPage.tsx +++ b/src/pages/NewReportWorkspaceSelectionPage.tsx @@ -99,7 +99,7 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`], reportNextStep, ); - clearSelectedTransactions(); + clearSelectedTransactions(true); Navigation.dismissModal(); Navigation.goBack(backTo ?? ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); return; @@ -107,16 +107,17 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag navigateToNewReport(optimisticReportID); }, [ - allReportNextSteps, - clearSelectedTransactions, currentUserPersonalDetails, isASAPSubmitBetaEnabled, + hasViolations, + selectedTransactions, isMovingExpenses, + selectedTransactionIDs, navigateToNewReport, + allReportNextSteps, policies, - selectedTransactionIDs, - selectedTransactions, - hasViolations, + clearSelectedTransactions, + backTo, ], ); From fbd7ad4eb4e82f40aefd7c2db07a6edd713f50d4 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 17:46:55 +0200 Subject: [PATCH 14/21] fix: eslint --- src/hooks/useSelectedTransactionsActions.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index a6478f93e36e0..555e1c8d55af8 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -305,20 +305,21 @@ function useSelectedTransactionsActions({ selectedTransactions, translate, isReportArchived, + policy, reportActions, clearSelectedTransactions, - onExportFailed, allTransactionsLength, + integrationsExportTemplates, + csvExportLayouts, + isOffline, + onExportOffline, + onExportFailed, + beginExportWithTemplate, + outstandingReportsByPolicyID, iouType, + lastVisitedPath, session?.accountID, showDeleteModal, - outstandingReportsByPolicyID, - policy, - beginExportWithTemplate, - isOffline, - onExportOffline, - csvExportLayouts, - integrationsExportTemplates, ]); return { From 40eb2ffa11eb78757509766199198c7a7faff5f0 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 Oct 2025 20:41:44 +0200 Subject: [PATCH 15/21] fix: minor fix --- src/components/ReportActionItem/MoneyRequestView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index a1176bc3e9e9d..4b0f219130de7 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -852,7 +852,7 @@ function MoneyRequestView({ iouType, transaction?.transactionID, report.reportID, - getReportRHPActiveRoute() ?? lastVisitedPath, + getReportRHPActiveRoute() || lastVisitedPath, ), ); }} From 8dc9a54d6ab363871acfefcce7ff0c5498fdad70 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 09:20:47 +0200 Subject: [PATCH 16/21] fix: clear selection --- src/pages/NewReportWorkspaceSelectionPage.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/NewReportWorkspaceSelectionPage.tsx b/src/pages/NewReportWorkspaceSelectionPage.tsx index 5a646f83a7abf..287785d8c670e 100644 --- a/src/pages/NewReportWorkspaceSelectionPage.tsx +++ b/src/pages/NewReportWorkspaceSelectionPage.tsx @@ -99,7 +99,11 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`], reportNextStep, ); - clearSelectedTransactions(true); + if (selectedTransactionIDs.length) { + clearSelectedTransactions(true); + } else if (selectedTransactionsKeys.length) { + clearSelectedTransactions(); + } Navigation.dismissModal(); Navigation.goBack(backTo ?? ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); return; From 5e3a865cbe3de6b475efd5684c18a80a4fd39f2e Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 12:43:07 +0200 Subject: [PATCH 17/21] fix: filter policies when no employeeList --- src/hooks/usePolicyForMovingExpenses.ts | 23 +++++++++++++++++++++-- src/libs/PolicyUtils.ts | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hooks/usePolicyForMovingExpenses.ts b/src/hooks/usePolicyForMovingExpenses.ts index c40db504955d5..e64e004159548 100644 --- a/src/hooks/usePolicyForMovingExpenses.ts +++ b/src/hooks/usePolicyForMovingExpenses.ts @@ -1,9 +1,21 @@ import {activePolicySelector} from '@selectors/Policy'; +import type {OnyxEntry} from 'react-native-onyx'; import {useSession} from '@components/OnyxListItemProvider'; -import {isPaidGroupPolicy, isPolicyMemberWithoutPendingDelete} from '@libs/PolicyUtils'; +import {isPaidGroupPolicy, isPolicyMemberWithoutPendingDelete, isPolicyUser, isUserPolicyAdmin} from '@libs/PolicyUtils'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import useOnyx from './useOnyx'; +// TODO: temporary util - if we don't have employeeList object we don't check for the pending delete +function checkForPendingDelete(login: string, policy: OnyxEntry) { + if (isEmptyObject(policy?.employeeList)) { + return true; + } + return isPolicyMemberWithoutPendingDelete(login, policy); +} + function usePolicyForMovingExpenses() { const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); @@ -13,7 +25,14 @@ function usePolicyForMovingExpenses() { }); const session = useSession(); - const userPolicies = Object.values(allPolicies ?? {}).filter((policy) => isPolicyMemberWithoutPendingDelete(session?.email, policy) && isPaidGroupPolicy(policy)); + const login = session?.email ?? ''; + const userPolicies = Object.values(allPolicies ?? {}).filter( + (policy) => + checkForPendingDelete(login, policy) && + (isUserPolicyAdmin(policy, login) || isPolicyUser(policy, login)) && + isPaidGroupPolicy(policy) && + policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + ); const isMemberOfMoreThanOnePolicy = userPolicies.length > 1; if (activePolicy) { diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 886d56a16e6e3..20a476b4b2559 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -341,7 +341,7 @@ function isExpensifyTeam(email: string | undefined): boolean { /** * Checks if the user with login is an admin of the policy. */ -const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); +const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => (getPolicyRole(policy, login) === CONST.POLICY.ROLE.ADMIN) || !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); /** * Checks if the current user is of the role "user" on the policy. From 71824a8222454eadf618ca5f0bcd97093b540c7a Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 13:17:33 +0200 Subject: [PATCH 18/21] fix: prettier --- src/libs/PolicyUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 20a476b4b2559..6c596e0dcff8f 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -341,7 +341,8 @@ function isExpensifyTeam(email: string | undefined): boolean { /** * Checks if the user with login is an admin of the policy. */ -const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => (getPolicyRole(policy, login) === CONST.POLICY.ROLE.ADMIN) || !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); +const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => + getPolicyRole(policy, login) === CONST.POLICY.ROLE.ADMIN || !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); /** * Checks if the current user is of the role "user" on the policy. From 697745083f43132853e87ce8dc9750cb7c28daf9 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 13:22:49 +0200 Subject: [PATCH 19/21] fix: use proper util --- src/hooks/usePolicyForMovingExpenses.ts | 4 ++-- src/libs/PolicyUtils.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hooks/usePolicyForMovingExpenses.ts b/src/hooks/usePolicyForMovingExpenses.ts index e64e004159548..f7ea1e21a75de 100644 --- a/src/hooks/usePolicyForMovingExpenses.ts +++ b/src/hooks/usePolicyForMovingExpenses.ts @@ -1,7 +1,7 @@ import {activePolicySelector} from '@selectors/Policy'; import type {OnyxEntry} from 'react-native-onyx'; import {useSession} from '@components/OnyxListItemProvider'; -import {isPaidGroupPolicy, isPolicyMemberWithoutPendingDelete, isPolicyUser, isUserPolicyAdmin} from '@libs/PolicyUtils'; +import {isPaidGroupPolicy, isPolicyAdmin, isPolicyMemberWithoutPendingDelete, isPolicyUser} from '@libs/PolicyUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy} from '@src/types/onyx'; @@ -29,7 +29,7 @@ function usePolicyForMovingExpenses() { const userPolicies = Object.values(allPolicies ?? {}).filter( (policy) => checkForPendingDelete(login, policy) && - (isUserPolicyAdmin(policy, login) || isPolicyUser(policy, login)) && + (isPolicyAdmin(policy, login) || isPolicyUser(policy, login)) && isPaidGroupPolicy(policy) && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, ); diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 6c596e0dcff8f..886d56a16e6e3 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -341,8 +341,7 @@ function isExpensifyTeam(email: string | undefined): boolean { /** * Checks if the user with login is an admin of the policy. */ -const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => - getPolicyRole(policy, login) === CONST.POLICY.ROLE.ADMIN || !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); +const isUserPolicyAdmin = (policy: OnyxInputOrEntry, login?: string) => !!(policy && policy.employeeList && login && policy.employeeList[login]?.role === CONST.POLICY.ROLE.ADMIN); /** * Checks if the current user is of the role "user" on the policy. From 411704785eb421a49e12c0af32c2dba37fe92c28 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 14:34:00 +0200 Subject: [PATCH 20/21] fix: check for auditor --- src/hooks/usePolicyForMovingExpenses.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hooks/usePolicyForMovingExpenses.ts b/src/hooks/usePolicyForMovingExpenses.ts index f7ea1e21a75de..7275bf1951215 100644 --- a/src/hooks/usePolicyForMovingExpenses.ts +++ b/src/hooks/usePolicyForMovingExpenses.ts @@ -1,7 +1,7 @@ import {activePolicySelector} from '@selectors/Policy'; import type {OnyxEntry} from 'react-native-onyx'; import {useSession} from '@components/OnyxListItemProvider'; -import {isPaidGroupPolicy, isPolicyAdmin, isPolicyMemberWithoutPendingDelete, isPolicyUser} from '@libs/PolicyUtils'; +import {getPolicyRole, isPaidGroupPolicy, isPolicyAdmin, isPolicyMemberWithoutPendingDelete, isPolicyUser} from '@libs/PolicyUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy} from '@src/types/onyx'; @@ -16,6 +16,10 @@ function checkForPendingDelete(login: string, policy: OnyxEntry) { return isPolicyMemberWithoutPendingDelete(login, policy); } +function isPolicyMemberByRole(login: string, policy: OnyxEntry) { + return isPolicyAdmin(policy, login) || isPolicyUser(policy, login) || getPolicyRole(policy, login) === CONST.POLICY.ROLE.AUDITOR; +} + function usePolicyForMovingExpenses() { const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); @@ -29,7 +33,7 @@ function usePolicyForMovingExpenses() { const userPolicies = Object.values(allPolicies ?? {}).filter( (policy) => checkForPendingDelete(login, policy) && - (isPolicyAdmin(policy, login) || isPolicyUser(policy, login)) && + isPolicyMemberByRole(login, policy) && isPaidGroupPolicy(policy) && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, ); From 0e028382309b1d6ad3d4a82fb9a0c1e213cc7990 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 8 Oct 2025 14:39:51 +0200 Subject: [PATCH 21/21] fix: prettier --- src/hooks/usePolicyForMovingExpenses.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hooks/usePolicyForMovingExpenses.ts b/src/hooks/usePolicyForMovingExpenses.ts index 7275bf1951215..ef508c8b1c0db 100644 --- a/src/hooks/usePolicyForMovingExpenses.ts +++ b/src/hooks/usePolicyForMovingExpenses.ts @@ -32,10 +32,7 @@ function usePolicyForMovingExpenses() { const login = session?.email ?? ''; const userPolicies = Object.values(allPolicies ?? {}).filter( (policy) => - checkForPendingDelete(login, policy) && - isPolicyMemberByRole(login, policy) && - isPaidGroupPolicy(policy) && - policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + checkForPendingDelete(login, policy) && isPolicyMemberByRole(login, policy) && isPaidGroupPolicy(policy) && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, ); const isMemberOfMoreThanOnePolicy = userPolicies.length > 1;