diff --git a/src/ROUTES.ts b/src/ROUTES.ts index dd66a515578fa..38f513fe8ea70 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/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index bc0d0dfc86859..4b0f219130de7 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, useContext, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; @@ -70,7 +69,6 @@ import { hasRoute as hasRouteTransactionUtils, isCardTransaction as isCardTransactionTransactionUtils, isDistanceRequest as isDistanceRequestTransactionUtils, - isExpenseUnreported as isExpenseUnreportedTransactionUtils, isManualDistanceRequest as isManualDistanceRequestTransactionUtils, isPerDiemRequest as isPerDiemRequestTransactionUtils, isScanning, @@ -131,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}`]; @@ -148,16 +147,10 @@ function MoneyRequestView({ return originalMessage?.IOUTransactionID; }, [parentReportAction]); 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}`]; @@ -250,9 +243,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(() => { @@ -272,11 +262,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 = @@ -284,7 +274,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; @@ -857,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/usePolicyForMovingExpenses.ts b/src/hooks/usePolicyForMovingExpenses.ts index c40db504955d5..ef508c8b1c0db 100644 --- a/src/hooks/usePolicyForMovingExpenses.ts +++ b/src/hooks/usePolicyForMovingExpenses.ts @@ -1,9 +1,25 @@ import {activePolicySelector} from '@selectors/Policy'; +import type {OnyxEntry} from 'react-native-onyx'; import {useSession} from '@components/OnyxListItemProvider'; -import {isPaidGroupPolicy, isPolicyMemberWithoutPendingDelete} 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'; +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 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}); @@ -13,7 +29,11 @@ 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) && isPolicyMemberByRole(login, policy) && isPaidGroupPolicy(policy) && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + ); const isMemberOfMoreThanOnePolicy = userPolicies.length > 1; if (activePolicy) { diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index 6838967311966..555e1c8d55af8 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); }, }); @@ -304,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 { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index e005058e3e7d9..a47dee09e7aad 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/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/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 5bfa24ba34a82..2be774826b284 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, @@ -1959,12 +1958,7 @@ function createUnreportedExpenseSections(transactions: Array; function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPageProps) { - const {isMovingExpenses} = route.params ?? {}; + const {isMovingExpenses, backTo} = route.params ?? {}; const {isOffline} = useNetwork(); - const {selectedTransactions, clearSelectedTransactions} = useSearchContext(); + const {selectedTransactions, selectedTransactionIDs, clearSelectedTransactions} = useSearchContext(); const styles = useThemeStyles(); const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); const {translate, localeCompare} = useLocalize(); @@ -87,10 +87,11 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag } const optimisticReportID = createNewReport(currentUserPersonalDetails, isASAPSubmitBetaEnabled, hasViolations, policyID); const selectedTransactionsKeys = Object.keys(selectedTransactions); - if (isMovingExpenses && !!selectedTransactionsKeys.length) { + + if (isMovingExpenses && (!!selectedTransactionsKeys.length || !!selectedTransactionIDs.length)) { const reportNextStep = allReportNextSteps?.[`${ONYXKEYS.COLLECTION.NEXT_STEP}${optimisticReportID}`]; changeTransactionsReport( - selectedTransactionsKeys, + selectedTransactionsKeys.length ? selectedTransactionsKeys : selectedTransactionIDs, optimisticReportID, isASAPSubmitBetaEnabled, currentUserPersonalDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID, @@ -98,23 +99,29 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`], reportNextStep, ); - clearSelectedTransactions(); + if (selectedTransactionIDs.length) { + clearSelectedTransactions(true); + } else if (selectedTransactionsKeys.length) { + clearSelectedTransactions(); + } Navigation.dismissModal(); - Navigation.goBack(ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); + Navigation.goBack(backTo ?? ROUTES.SEARCH_ROOT.getRoute({query: buildCannedSearchQuery()})); return; } navigateToNewReport(optimisticReportID); }, [ - allReportNextSteps, - clearSelectedTransactions, currentUserPersonalDetails, isASAPSubmitBetaEnabled, + hasViolations, + selectedTransactions, isMovingExpenses, + selectedTransactionIDs, navigateToNewReport, + allReportNextSteps, policies, - selectedTransactions, - hasViolations, + clearSelectedTransactions, + backTo, ], ); diff --git a/src/pages/Search/SearchTransactionsChangeReport.tsx b/src/pages/Search/SearchTransactionsChangeReport.tsx index 9148c64780332..3cf1c49392c5b 100644 --- a/src/pages/Search/SearchTransactionsChangeReport.tsx +++ b/src/pages/Search/SearchTransactionsChangeReport.tsx @@ -28,10 +28,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 d98b3eca86e8a..94de2ddeb6d07 100644 --- a/src/pages/iou/request/step/IOURequestEditReport.tsx +++ b/src/pages/iou/request/step/IOURequestEditReport.tsx @@ -2,13 +2,18 @@ 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 {hasViolations as hasViolationsReportUtils} from '@libs/ReportUtils'; +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 +38,10 @@ 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 [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); + const hasViolations = hasViolationsReportUtils(undefined, transactionViolations); const selectReport = (item: TransactionGroupListItem) => { if (selectedTransactionIDs.length === 0 || item.value === reportID) { @@ -67,6 +76,15 @@ function IOURequestEditReport({route}: IOURequestEditReportProps) { Navigation.dismissModal(); }; + const createReport = () => { + if (shouldSelectPolicy) { + Navigation.navigate(ROUTES.NEW_REPORT_WORKSPACE_SELECTION.getRoute(true, backTo)); + return; + } + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); + selectReport({value: createdReportID}); + }; + return ( ); } diff --git a/src/pages/iou/request/step/IOURequestEditReportCommon.tsx b/src/pages/iou/request/step/IOURequestEditReportCommon.tsx index 6644ae32a1b2c..f1ae4bb22d6d8 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/IOURequestStepCategory.tsx b/src/pages/iou/request/step/IOURequestStepCategory.tsx index 5883ed8ec7ae0..f2e90b9e3279b 100644 --- a/src/pages/iou/request/step/IOURequestStepCategory.tsx +++ b/src/pages/iou/request/step/IOURequestStepCategory.tsx @@ -1,4 +1,3 @@ -import {activePolicySelector} from '@selectors/Policy'; import lodashIsEmpty from 'lodash/isEmpty'; import React, {useEffect} from 'react'; import {InteractionManager, View} from 'react-native'; @@ -24,7 +23,6 @@ import Navigation from '@libs/Navigation/Navigation'; import {hasEnabledOptions} from '@libs/OptionsListUtils'; import {isPolicyAdmin} from '@libs/PolicyUtils'; import {getTransactionDetails, isGroupPolicy, isReportInGroupPolicy} from '@libs/ReportUtils'; -import {isExpenseUnreported as isExpenseUnreportedTransactionUtils} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -53,13 +51,7 @@ function IOURequestStepCategory({ const policyIdDraft = getIOURequestPolicyID(transaction, reportDraft); const [policyReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyIdReal}`, {canBeMissing: true}); const [policyDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyIdDraft}`, {canBeMissing: true}); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, { - canBeMissing: true, - selector: activePolicySelector, - }); - const isExpenseUnreported = isExpenseUnreportedTransactionUtils(transaction); - const policy = isExpenseUnreported ? activePolicy : (policyReal ?? policyDraft); + const policy = policyReal ?? policyDraft; const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`, {canBeMissing: true}); const [policyCategoriesReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policy?.id}`, {canBeMissing: true}); @@ -79,7 +71,7 @@ function IOURequestStepCategory({ const categoryForDisplay = isCategoryMissing(transactionCategory) ? '' : transactionCategory; const shouldShowCategory = - (isExpenseUnreported || isReportInGroupPolicy(report) || isGroupPolicy(policy?.type ?? '')) && + (isReportInGroupPolicy(report) || isGroupPolicy(policy?.type ?? '')) && // The transactionCategory can be an empty string, so to maintain the logic we'd like to keep it in this shape until utils refactor // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (!!categoryForDisplay || hasEnabledOptions(Object.values(policyCategories ?? {}))); diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index e8a9c55ac27ec..594e8d52df3c0 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -3,12 +3,15 @@ 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'; -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'; @@ -38,7 +41,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { const selectedReportID = shouldUseTransactionReport ? transactionReport?.reportID : outstandingReportID; const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); const [allPolicyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}`, {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; @@ -46,6 +49,10 @@ 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 [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); + const hasViolations = hasViolationsReportUtils(undefined, transactionViolations); const handleGoBack = () => { if (isEditing) { @@ -163,6 +170,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, backTo)); + return; + } + const createdReportID = createNewReport(currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policyForMovingExpensesID); + handleRegularReportSelection({value: createdReportID}); + }; + return ( ); } diff --git a/src/pages/iou/request/step/IOURequestStepTag.tsx b/src/pages/iou/request/step/IOURequestStepTag.tsx index dc7c33ea40de4..88588e1f29b09 100644 --- a/src/pages/iou/request/step/IOURequestStepTag.tsx +++ b/src/pages/iou/request/step/IOURequestStepTag.tsx @@ -1,4 +1,3 @@ -import {activePolicySelector} from '@selectors/Policy'; import React, {useMemo} from 'react'; import {View} from 'react-native'; import Button from '@components/Button'; @@ -18,7 +17,7 @@ import Navigation from '@libs/Navigation/Navigation'; import {getTagList, getTagListName, getTagLists, hasDependentTags as hasDependentTagsPolicyUtils, isPolicyAdmin} from '@libs/PolicyUtils'; import type {OptionData} from '@libs/ReportUtils'; import {hasEnabledTags} from '@libs/TagsOptionsListUtils'; -import {getTag, getTagArrayFromName, isExpenseUnreported as isExpenseUnreportedTransactionUtils} from '@libs/TransactionUtils'; +import {getTag, getTagArrayFromName} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -40,14 +39,7 @@ function IOURequestStepTag({ transaction, }: IOURequestStepTagProps) { const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`, {canBeMissing: true}); - const [reportPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: false}); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, { - canBeMissing: true, - selector: activePolicySelector, - }); - const isExpenseUnreported = isExpenseUnreportedTransactionUtils(transaction); - const policy = isExpenseUnreported ? activePolicy : reportPolicy; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: false}); const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policy?.id}`, {canBeMissing: false}); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`, {canBeMissing: false}); diff --git a/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx b/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx index 2b10f738b72dd..a51d21fef624a 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx +++ b/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx @@ -1,4 +1,3 @@ -import {activePolicySelector} from '@selectors/Policy'; import React from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import TaxPicker from '@components/TaxPicker'; @@ -7,7 +6,7 @@ import useOnyx from '@hooks/useOnyx'; import {convertToBackendAmount} from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {TaxRatesOption} from '@libs/TaxOptionsListUtils'; -import {calculateTaxAmount, getAmount, getCurrency, getTaxName, getTaxValue, isExpenseUnreported as isExpenseUnreportedTransactionUtils} from '@libs/TransactionUtils'; +import {calculateTaxAmount, getAmount, getCurrency, getTaxName, getTaxValue} from '@libs/TransactionUtils'; import {setDraftSplitTransaction, setMoneyRequestTaxAmount, setMoneyRequestTaxRate, updateMoneyRequestTaxRate} from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -39,14 +38,7 @@ function IOURequestStepTaxRatePage({ }: IOURequestStepTaxRatePageProps) { const {translate} = useLocalize(); - const [reportPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: true}); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, { - canBeMissing: true, - selector: activePolicySelector, - }); - const isExpenseUnreported = isExpenseUnreportedTransactionUtils(transaction); - const policy = isExpenseUnreported ? activePolicy : reportPolicy; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: true}); const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policy?.id}`, {canBeMissing: true}); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`, {canBeMissing: true}); const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`, {canBeMissing: true});