diff --git a/src/CONST.ts b/src/CONST.ts index 204feb44b089..585a6dc46852 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1617,6 +1617,27 @@ const CONST = { DISABLE: 'disable', ENABLE: 'enable', }, + DEFAULT_CATEGORIES: [ + 'Advertising', + 'Benefits', + 'Car', + 'Equipment', + 'Fees', + 'Home Office', + 'Insurance', + 'Interest', + 'Labor', + 'Maintenance', + 'Materials', + 'Meals and Entertainment', + 'Office Supplies', + 'Other', + 'Professional Services', + 'Rent', + 'Taxes', + 'Travel', + 'Utilities', + ], OWNERSHIP_ERRORS: { NO_BILLING_CARD: 'noBillingCard', AMOUNT_OWED: 'amountOwed', diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f92106d40b6e..0832ac0c458d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -55,6 +55,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; import * as IOU from './actions/IOU'; +import * as PolicyActions from './actions/Policy'; import * as store from './actions/ReimbursementAccount/store'; import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; @@ -6116,7 +6117,34 @@ function createDraftTransactionAndNavigateToParticipantSelector(transactionID: s mccGroup, } as Transaction); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(CONST.IOU.TYPE.SUBMIT, transactionID, reportID, undefined, actionName)); + const filteredPolicies = Object.values(allPolicies ?? {}).filter( + (policy) => policy?.type !== CONST.POLICY.TYPE.PERSONAL && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + ); + + if (actionName === CONST.IOU.ACTION.SUBMIT || (allPolicies && filteredPolicies.length > 0)) { + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(CONST.IOU.TYPE.SUBMIT, transactionID, reportID, undefined, actionName)); + return; + } + + const {expenseChatReportID, policyID, policyName} = PolicyActions.createWorkspace(); + const isCategorizing = actionName === CONST.IOU.ACTION.CATEGORIZE; + + IOU.setMoneyRequestParticipants(transactionID, [ + { + selected: true, + accountID: 0, + isPolicyExpenseChat: true, + reportID: expenseChatReportID, + policyID, + searchText: policyName, + }, + ]); + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID); + if (isCategorizing) { + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, expenseChatReportID, iouConfirmationPageRoute)); + } else { + Navigation.navigate(iouConfirmationPageRoute); + } } /** diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index d291bff86efa..6b8514beab82 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -2075,6 +2075,69 @@ function createDraftInitialWorkspace(policyOwnerEmail = '', policyName = '', pol Onyx.update(optimisticData); } +function buildOptimisticPolicyCategories(policyID: string, categories: readonly string[]) { + const optimisticCategoryMap = categories.reduce( + (acc, category) => ({ + ...acc, + [category]: { + name: category, + enabled: true, + errors: null, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }), + {}, + ); + + const successCategoryMap = categories.reduce( + (acc, category) => ({ + ...acc, + [category]: { + errors: null, + pendingAction: null, + }, + }), + {}, + ); + + const failureCategoryMap = categories.reduce( + (acc, category) => ({ + ...acc, + [category]: { + errors: ErrorUtils.getMicroSecondOnyxError('workspace.categories.createFailureMessage'), + pendingAction: null, + }, + }), + {}, + ); + + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: optimisticCategoryMap, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: successCategoryMap, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: failureCategoryMap, + }, + ], + }; + + return onyxData; +} + /** * Optimistically creates a new workspace and default workspace chats * @@ -2083,7 +2146,7 @@ function createDraftInitialWorkspace(policyOwnerEmail = '', policyName = '', pol * @param [policyName] custom policy name we will use for created workspace * @param [policyID] custom policy id we will use for created workspace */ -function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName = '', policyID = generatePolicyID()): string { +function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName = '', policyID = generatePolicyID()): CreateWorkspaceParams { const workspaceName = policyName || generateDefaultWorkspaceName(policyOwnerEmail); const {customUnits, customUnitID, customUnitRateID, outputCurrency} = buildOptimisticCustomUnits(); @@ -2103,6 +2166,8 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName expenseCreatedReportActionID, } = ReportUtils.buildOptimisticWorkspaceChats(policyID, workspaceName); + const optimisticCategoriesData = buildOptimisticPolicyCategories(policyID, CONST.POLICY.DEFAULT_CATEGORIES); + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, @@ -2293,6 +2358,18 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName }, ]; + if (optimisticCategoriesData.optimisticData) { + optimisticData.push(...optimisticCategoriesData.optimisticData); + } + + if (optimisticCategoriesData.failureData) { + failureData.push(...optimisticCategoriesData.failureData); + } + + if (optimisticCategoriesData.successData) { + successData.push(...optimisticCategoriesData.successData); + } + const params: CreateWorkspaceParams = { policyID, announceChatReportID, @@ -2311,7 +2388,7 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData}); - return adminsChatReportID; + return params; } function openWorkspaceReimburseView(policyID: string) { @@ -3085,46 +3162,7 @@ function setWorkspaceCategoryEnabled(policyID: string, categoriesToUpdate: Recor } function createPolicyCategory(policyID: string, categoryName: string) { - const onyxData: OnyxData = { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, - value: { - [categoryName]: { - name: categoryName, - enabled: true, - errors: null, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - }, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, - value: { - [categoryName]: { - errors: null, - pendingAction: null, - }, - }, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, - value: { - [categoryName]: { - errors: ErrorUtils.getMicroSecondOnyxError('workspace.categories.createFailureMessage'), - pendingAction: null, - }, - }, - }, - ], - }; + const onyxData = buildOptimisticPolicyCategories(policyID, [categoryName]); const parameters = { policyID, diff --git a/src/pages/OnboardingWork/BaseOnboardingWork.tsx b/src/pages/OnboardingWork/BaseOnboardingWork.tsx index 1236a8178796..151c1bb35ea2 100644 --- a/src/pages/OnboardingWork/BaseOnboardingWork.tsx +++ b/src/pages/OnboardingWork/BaseOnboardingWork.tsx @@ -43,7 +43,7 @@ function BaseOnboardingWork({currentUserPersonalDetails, shouldUseNativeStyles, const work = values.work.trim(); - const adminsChatReportID = Policy.createWorkspace(undefined, true, work); + const {adminsChatReportID} = Policy.createWorkspace(undefined, true, work); Report.completeOnboarding( onboardingPurposeSelected, diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 762198090467..0596e419846d 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -1,4 +1,3 @@ -import lodashEvery from 'lodash/every'; import lodashGet from 'lodash/get'; import lodashIsEqual from 'lodash/isEqual'; import lodashMap from 'lodash/map'; @@ -9,11 +8,8 @@ import lodashValues from 'lodash/values'; import PropTypes from 'prop-types'; import React, {memo, useCallback, useEffect, useMemo} from 'react'; import {useOnyx} from 'react-native-onyx'; -import BlockingView from '@components/BlockingViews/BlockingView'; import Button from '@components/Button'; import FormHelpMessage from '@components/FormHelpMessage'; -import * as Illustrations from '@components/Icon/Illustrations'; -import OfflineIndicator from '@components/OfflineIndicator'; import {usePersonalDetails} from '@components/OnyxProvider'; import {useOptionsList} from '@components/OptionListContextProvider'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; @@ -26,15 +22,11 @@ import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; import useScreenWrapperTranstionStatus from '@hooks/useScreenWrapperTransitionStatus'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; const propTypes = { /** Callback to request parent modal to go to next step, which should be split */ @@ -87,7 +79,6 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({participants, onF const offlineMessage = isOffline ? [`${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}`, {isTranslated: true}] : ''; const maxParticipantsReached = participants.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; - const {isSmallScreenWidth} = useWindowDimensions(); const isIOUSplit = iouType === CONST.IOU.TYPE.SPLIT; const isCategorizeOrShareAction = [CONST.IOU.ACTION.CATEGORIZE, CONST.IOU.ACTION.SHARE].includes(action); @@ -335,31 +326,6 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({participants, onF ); }, [handleConfirmSelection, participants.length, isDismissed, referralContentType, shouldShowSplitBillErrorMessage, styles, translate]); - const renderEmptyWorkspaceView = () => ( - <> - -