diff --git a/src/components/AddExistingExpenseFooter.tsx b/src/components/AddExistingExpenseFooter.tsx index ab1f26456178..073f00dc2d13 100644 --- a/src/components/AddExistingExpenseFooter.tsx +++ b/src/components/AddExistingExpenseFooter.tsx @@ -112,6 +112,7 @@ function AddExistingExpenseFooter({selectedIds, report, reportToConfirm, policy, isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); } diff --git a/src/components/MoneyReportHeaderEducationalModals.tsx b/src/components/MoneyReportHeaderEducationalModals.tsx index 60057672e56e..fbc3a286f5a5 100644 --- a/src/components/MoneyReportHeaderEducationalModals.tsx +++ b/src/components/MoneyReportHeaderEducationalModals.tsx @@ -1,4 +1,5 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -49,6 +50,7 @@ function MoneyReportHeaderEducationalModals({reportID, ref}: MoneyReportHeaderEd const [shouldFailAllRequests] = useOnyx(ONYXKEYS.NETWORK, {selector: shouldFailAllRequestsSelector}); const {login: currentUserLogin, accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(moneyRequestReport?.chatReportID)}`); @@ -66,7 +68,16 @@ function MoneyReportHeaderEducationalModals({reportID, ref}: MoneyReportHeaderEd setIsHoldEducationalModalVisible(false); setNameValuePair(ONYXKEYS.NVP_DISMISSED_HOLD_USE_EXPLANATION, true, false, !shouldFailAllRequests); if (requestParentReportAction) { - changeMoneyRequestHoldStatus(requestParentReportAction, transaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + requestParentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); } }; @@ -74,7 +85,16 @@ function MoneyReportHeaderEducationalModals({reportID, ref}: MoneyReportHeaderEd if (rejectModalAction === CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD) { dismissRejectUseExplanation(); if (requestParentReportAction) { - changeMoneyRequestHoldStatus(requestParentReportAction, transaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + requestParentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); } } else if (rejectModalAction === CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT_BULK) { dismissRejectUseExplanation(); diff --git a/src/components/MoneyReportHeaderPrimaryAction/RemoveHoldPrimaryAction.tsx b/src/components/MoneyReportHeaderPrimaryAction/RemoveHoldPrimaryAction.tsx index 2b5df7d50f33..f94c91b1ee56 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/RemoveHoldPrimaryAction.tsx +++ b/src/components/MoneyReportHeaderPrimaryAction/RemoveHoldPrimaryAction.tsx @@ -2,6 +2,7 @@ import Button from '@components/ButtonComposed'; import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useTransactionsAndViolationsForReport from '@hooks/useTransactionsAndViolationsForReport'; @@ -27,6 +28,7 @@ function RemoveHoldPrimaryAction({reportID, chatReportID}: SimpleActionProps) { const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); const {login: currentUserLogin, accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const {moneyRequestReport, isOffline, reportActions, transactionThreadReportID, requestParentReportAction} = useTransactionThreadData(reportID, chatReportID); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(moneyRequestReport?.policyID)}`); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); @@ -51,7 +53,16 @@ function RemoveHoldPrimaryAction({reportID, chatReportID}: SimpleActionProps) { for (const action of IOUActions) { const linkedTransaction = getLinkedIOUTransaction(action, transactions); const transactionViolations = allTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${linkedTransaction?.transactionID}`]; - changeMoneyRequestHoldStatus(action, linkedTransaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + action, + linkedTransaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); } return; } @@ -63,7 +74,16 @@ function RemoveHoldPrimaryAction({reportID, chatReportID}: SimpleActionProps) { const linkedTransaction = getLinkedIOUTransaction(moneyRequestAction, transactions); const transactionViolations = allTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${linkedTransaction?.transactionID}`]; - changeMoneyRequestHoldStatus(moneyRequestAction, linkedTransaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + moneyRequestAction, + linkedTransaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); }} > {translate('iou.unhold')} diff --git a/src/components/MoneyRequestHeaderPrimaryAction.tsx b/src/components/MoneyRequestHeaderPrimaryAction.tsx index 5759a9ea1739..5e9c11b2f95d 100644 --- a/src/components/MoneyRequestHeaderPrimaryAction.tsx +++ b/src/components/MoneyRequestHeaderPrimaryAction.tsx @@ -1,4 +1,5 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDuplicateTransactionsAndViolations from '@hooks/useDuplicateTransactionsAndViolations'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -46,6 +47,7 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc const styles = useThemeStyles(); const {translate} = useLocalize(); const {login: currentUserLogin, accountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth @@ -97,7 +99,16 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc showDelegateNoAccessModal(); return; } - changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + parentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + accountID, + rawTransactionViolations, + isTrackIntentUser, + delegateAccountID, + ); }} /> ); diff --git a/src/components/MoneyRequestHeaderSecondaryActions.tsx b/src/components/MoneyRequestHeaderSecondaryActions.tsx index 6b1fcc511ef9..c576a7a10461 100644 --- a/src/components/MoneyRequestHeaderSecondaryActions.tsx +++ b/src/components/MoneyRequestHeaderSecondaryActions.tsx @@ -289,7 +289,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money setIsHoldEducationalModalVisible(false); setNameValuePair(ONYXKEYS.NVP_DISMISSED_HOLD_USE_EXPLANATION, true, false, !shouldFailAllRequests); if (parentReportAction) { - changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser, delegateAccountID); } }; @@ -297,7 +297,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money if (rejectModalAction === CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD) { dismissRejectUseExplanation(); if (parentReportAction) { - changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser, delegateAccountID); } } else { dismissRejectUseExplanation(); @@ -352,7 +352,16 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money const shouldShowHoldEducationalModal = isReportSubmitter || isParentChatReportDM; const isDismissed = shouldShowHoldEducationalModal ? dismissedHoldUseExplanation : dismissedRejectUseExplanation; if (isDismissed) { - changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + parentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + accountID, + rawTransactionViolations, + isTrackIntentUser, + delegateAccountID, + ); } else if (shouldShowHoldEducationalModal) { setIsHoldEducationalModalVisible(true); } else { @@ -374,7 +383,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money return; } - changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus(parentReportAction, transaction, isOffline, currentUserLogin ?? '', accountID, rawTransactionViolations, isTrackIntentUser, delegateAccountID); }, }, [CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.SPLIT]: { diff --git a/src/hooks/useExpenseActions.ts b/src/hooks/useExpenseActions.ts index dacef37d1945..b0a034446845 100644 --- a/src/hooks/useExpenseActions.ts +++ b/src/hooks/useExpenseActions.ts @@ -623,6 +623,7 @@ function useExpenseActions({reportID, isReportInSearch = false, backTo, onDuplic reportTransactions, allTransactionViolations, bankAccountList, + delegateAccountID, hash: currentSearchHash, }); }, CONST.EXPENSE_REPORT_DELETE_DELAY_MS); diff --git a/src/hooks/useHoldRejectActions.ts b/src/hooks/useHoldRejectActions.ts index 13105a2a95a9..fed3e857712f 100644 --- a/src/hooks/useHoldRejectActions.ts +++ b/src/hooks/useHoldRejectActions.ts @@ -16,6 +16,7 @@ import type {ValueOf} from 'type-fest'; import {isTrackIntentUserSelector} from '@selectors/Onboarding'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; +import useDelegateAccountID from './useDelegateAccountID'; import useGetIOUReportFromReportAction from './useGetIOUReportFromReportAction'; import {useMemoizedLazyExpensifyIcons} from './useLazyAsset'; import useLocalize from './useLocalize'; @@ -46,6 +47,7 @@ function useHoldRejectActions({reportID, onHoldEducationalOpen, onRejectModalOpe const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(moneyRequestReport?.chatReportID)}`); const {iouTransactionID, requestParentReportAction} = useMoneyReportTransactionThread(); const {login: currentUserLogin, accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const {chatReport: chatIOUReport} = useGetIOUReportFromReportAction(requestParentReportAction); @@ -80,7 +82,16 @@ function useHoldRejectActions({reportID, onHoldEducationalOpen, onRejectModalOpe const isDismissed = shouldShowHoldEducationalModal ? dismissedHoldUseExplanation : dismissedRejectUseExplanation; if (isDismissed || shouldSuppressPromotionalUI) { - changeMoneyRequestHoldStatus(requestParentReportAction, transaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + requestParentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); } else if (shouldShowHoldEducationalModal) { onHoldEducationalOpen(); } else { @@ -103,7 +114,16 @@ function useHoldRejectActions({reportID, onHoldEducationalOpen, onRejectModalOpe return; } - changeMoneyRequestHoldStatus(requestParentReportAction, transaction, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + changeMoneyRequestHoldStatus( + requestParentReportAction, + transaction, + isOffline, + currentUserLogin ?? '', + currentUserAccountID, + transactionViolations, + isTrackIntentUser, + delegateAccountID, + ); }, }, [CONST.REPORT.SECONDARY_ACTIONS.REJECT]: { diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index ca915e7755a1..880103b8bdaa 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -1085,6 +1085,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { reportTransactions: validTransactions, allTransactionViolations, bankAccountList, + delegateAccountID, hash, }); } @@ -1134,6 +1135,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { reportTransactions: validTransactions, allTransactionViolations: transactionsViolations, bankAccountList, + delegateAccountID, }); } } @@ -1159,6 +1161,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { deleteTransactionsFromHook, duplicateTransactions, duplicateTransactionViolations, + delegateAccountID, ]); const onBulkPaySelected = useCallback( @@ -2195,6 +2198,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { accountID, transactionViolations, isTrackIntentUser, + delegateAccountID, ); } clearSelectedTransactions(); @@ -2455,6 +2459,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { allReportsShouldMarkAsDone, noReportsShouldMarkAsDone, queryJSON?.groupBy, + delegateAccountID, ]); const handleOfflineModalClose = useCallback(() => { diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index 1073f25ba239..a82ad81eeca7 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -46,6 +46,7 @@ import useConfirmModal from './useConfirmModal'; import {useCurrencyListActions} from './useCurrencyList'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; import useDefaultExpensePolicy from './useDefaultExpensePolicy'; +import useDelegateAccountID from './useDelegateAccountID'; import useDeleteTransactions from './useDeleteTransactions'; import useDuplicateTransactionsAndViolations from './useDuplicateTransactionsAndViolations'; import useEnvironment from './useEnvironment'; @@ -128,6 +129,7 @@ function useSelectedTransactionsActions({ const {isBetaEnabled} = usePermissions(); const {deleteTransactions, shouldOpenSplitExpenseEditFlowOnDelete} = useDeleteTransactions({report, reportActions, policy}); const {login, accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const defaultExpensePolicy = useDefaultExpensePolicy(); const {isProduction} = useEnvironment(); @@ -359,7 +361,7 @@ function useSelectedTransactionsActions({ continue; } const transactionViolations = allTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]; - unholdRequest(transactionID, action.childReportID, policy, isOffline, login ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser); + unholdRequest(transactionID, action.childReportID, policy, isOffline, login ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser, delegateAccountID); } clearSelectedTransactions(true); }, diff --git a/src/hooks/useUndeleteTransactions.ts b/src/hooks/useUndeleteTransactions.ts index bf2af16e2800..30e01c17ee8e 100644 --- a/src/hooks/useUndeleteTransactions.ts +++ b/src/hooks/useUndeleteTransactions.ts @@ -9,11 +9,13 @@ import {isTrackIntentUserSelector} from '@selectors/Onboarding'; import {useCurrencyListActions} from './useCurrencyList'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; +import useDelegateAccountID from './useDelegateAccountID'; import useOnyx from './useOnyx'; import usePermissions from './usePermissions'; function useUndeleteTransactions() { const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const {getCurrencyDecimals} = useCurrencyListActions(); const {isBetaEnabled} = usePermissions(); const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); @@ -42,6 +44,7 @@ function useUndeleteTransactions() { selfDMReportActions, isTrackIntentUser, personalPolicyOutputCurrency: policy?.outputCurrency, + delegateAccountID, getCurrencyDecimals, }); }; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 5c5a82bf2f64..ccc8ac9dcf91 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -546,12 +546,36 @@ type OptimisticSubmittedReportAction = Pick< type OptimisticHoldReportAction = Pick< ReportAction, - 'actionName' | 'actorAccountID' | 'automatic' | 'avatar' | 'isAttachmentOnly' | 'originalMessage' | 'message' | 'person' | 'reportActionID' | 'shouldShow' | 'created' | 'pendingAction' + | 'actionName' + | 'actorAccountID' + | 'automatic' + | 'avatar' + | 'isAttachmentOnly' + | 'originalMessage' + | 'message' + | 'person' + | 'reportActionID' + | 'shouldShow' + | 'created' + | 'pendingAction' + | 'delegateAccountID' >; type OptimisticRejectReportAction = Pick< ReportAction, - 'actionName' | 'actorAccountID' | 'automatic' | 'avatar' | 'isAttachmentOnly' | 'originalMessage' | 'message' | 'person' | 'reportActionID' | 'shouldShow' | 'created' | 'pendingAction' + | 'actionName' + | 'actorAccountID' + | 'automatic' + | 'avatar' + | 'isAttachmentOnly' + | 'originalMessage' + | 'message' + | 'person' + | 'reportActionID' + | 'shouldShow' + | 'created' + | 'pendingAction' + | 'delegateAccountID' >; type OptimisticReopenedReportAction = Pick< @@ -5494,6 +5518,7 @@ const changeMoneyRequestHoldStatus = ( currentUserAccountID: number, transactionViolations: OnyxEntry, isTrackIntentUser: boolean | undefined, + delegateAccountID: number | undefined, ): void => { if (!isMoneyRequestAction(reportAction)) { return; @@ -5517,7 +5542,7 @@ const changeMoneyRequestHoldStatus = ( if (isOnHold) { if (reportAction.childReportID) { - unholdRequest(transactionID, reportAction.childReportID, policy, isOffline, currentUserLogin, currentUserAccountID, transactionViolations, isTrackIntentUser); + unholdRequest(transactionID, reportAction.childReportID, policy, isOffline, currentUserLogin, currentUserAccountID, transactionViolations, isTrackIntentUser, delegateAccountID); } else { Log.warn('Missing reportAction.childReportID during money request unhold'); } @@ -8471,7 +8496,7 @@ function buildOptimisticRoomAvatarUpdatedReportAction(avatarURL: string): Optimi * Returns the necessary reportAction onyx data to indicate that the transaction has been put on hold optimistically * @param [created] - Action created time */ -function buildOptimisticHoldReportAction(created = DateUtils.getDBTime()): OptimisticHoldReportAction { +function buildOptimisticHoldReportAction(delegateAccountID: number | undefined, created = DateUtils.getDBTime()): OptimisticHoldReportAction { return { reportActionID: rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.HOLD, @@ -8495,6 +8520,7 @@ function buildOptimisticHoldReportAction(created = DateUtils.getDBTime()): Optim avatar: getCurrentUserAvatar(), created, shouldShow: true, + delegateAccountID, }; } @@ -8502,7 +8528,7 @@ function buildOptimisticHoldReportAction(created = DateUtils.getDBTime()): Optim * Returns the necessary reportAction onyx data to indicate that the transaction has been put on hold optimistically * @param [created] - Action created time */ -function buildOptimisticHoldReportActionComment(comment: string, created = DateUtils.getDBTime()): OptimisticHoldReportAction { +function buildOptimisticHoldReportActionComment(comment: string, delegateAccountID: number | undefined, created = DateUtils.getDBTime()): OptimisticHoldReportAction { return { reportActionID: rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, @@ -8526,6 +8552,7 @@ function buildOptimisticHoldReportActionComment(comment: string, created = DateU avatar: getCurrentUserAvatar(), created, shouldShow: true, + delegateAccountID, }; } @@ -8533,7 +8560,7 @@ function buildOptimisticHoldReportActionComment(comment: string, created = DateU * Returns the necessary reportAction onyx data to indicate that the transaction has been removed from hold optimistically * @param [created] - Action created time */ -function buildOptimisticUnHoldReportAction(created = DateUtils.getDBTime()): OptimisticHoldReportAction { +function buildOptimisticUnHoldReportAction(delegateAccountID: number | undefined, created = DateUtils.getDBTime()): OptimisticHoldReportAction { return { reportActionID: rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.UNHOLD, @@ -8557,6 +8584,7 @@ function buildOptimisticUnHoldReportAction(created = DateUtils.getDBTime()): Opt avatar: getCurrentUserAvatar(), created, shouldShow: true, + delegateAccountID, }; } @@ -13442,7 +13470,7 @@ function selectFilteredReportActions( * Returns the necessary reportAction onyx data to indicate that the transaction has been rejected optimistically * @param [created] - Action created time */ -function buildOptimisticRejectReportAction(created = DateUtils.getDBTime()): OptimisticRejectReportAction { +function buildOptimisticRejectReportAction(delegateAccountID: number | undefined, created = DateUtils.getDBTime()): OptimisticRejectReportAction { return { reportActionID: rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.REJECTEDTRANSACTION_THREAD, @@ -13466,6 +13494,7 @@ function buildOptimisticRejectReportAction(created = DateUtils.getDBTime()): Opt avatar: getCurrentUserAvatar(), created, shouldShow: true, + delegateAccountID, }; } @@ -13473,7 +13502,7 @@ function buildOptimisticRejectReportAction(created = DateUtils.getDBTime()): Opt * Returns the necessary reportAction onyx data to indicate that the transaction has been rejected optimistically * @param [created] - Action created time */ -function buildOptimisticRejectReportActionComment(comment: string, created = DateUtils.getDBTime()): OptimisticRejectReportAction { +function buildOptimisticRejectReportActionComment(comment: string, delegateAccountID: number | undefined, created = DateUtils.getDBTime()): OptimisticRejectReportAction { return { reportActionID: rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, @@ -13497,6 +13526,7 @@ function buildOptimisticRejectReportActionComment(comment: string, created = Dat avatar: getCurrentUserAvatar(), created, shouldShow: true, + delegateAccountID, }; } @@ -13509,6 +13539,7 @@ function buildOptimisticReportLevelRejectAction( actorAccountID: number | undefined, currentUserDisplayName: string | undefined, currentUserAvatarSource: AvatarSource | undefined, + delegateAccountID: number | undefined, created = DateUtils.getDBTime(), ): OptimisticRejectReportAction { return { @@ -13534,6 +13565,7 @@ function buildOptimisticReportLevelRejectAction( avatar: currentUserAvatarSource, created, shouldShow: true, + delegateAccountID, }; } @@ -13545,6 +13577,7 @@ function buildOptimisticReportLevelRejectCommentAction( actorAccountID: number | undefined, currentUserDisplayName: string | undefined, currentUserAvatarSource: AvatarSource | undefined, + delegateAccountID: number | undefined, created = DateUtils.getDBTime(), ): OptimisticRejectReportAction { return { @@ -13570,6 +13603,7 @@ function buildOptimisticReportLevelRejectCommentAction( avatar: currentUserAvatarSource, created, shouldShow: true, + delegateAccountID, }; } diff --git a/src/libs/actions/IOU/Duplicate.ts b/src/libs/actions/IOU/Duplicate.ts index 8a93c93e3efd..b1b9b9995778 100644 --- a/src/libs/actions/IOU/Duplicate.ts +++ b/src/libs/actions/IOU/Duplicate.ts @@ -441,6 +441,7 @@ function resolveDuplicates({ transactionThreadReportIDMap, allTransactionViolations, allReportActionsList, + delegateAccountID, ...params }: MergeDuplicatesParams & { taxAmount?: number; @@ -448,6 +449,7 @@ function resolveDuplicates({ transactionThreadReportIDMap: Record; allTransactionViolations: OnyxCollection; allReportActionsList: OnyxCollection; + delegateAccountID: number | undefined; }) { if (!params.transactionID) { return; @@ -513,7 +515,7 @@ function resolveDuplicates({ continue; } - const createdReportAction = buildOptimisticHoldReportAction(); + const createdReportAction = buildOptimisticHoldReportAction(delegateAccountID); reportActionIDList.push(createdReportAction.reportActionID); resolvedTransactionIDList.push(transactionID); optimisticHoldTransactionActions.push({ diff --git a/src/libs/actions/IOU/Hold.ts b/src/libs/actions/IOU/Hold.ts index 2abd57421d62..8fa1e5e63e4e 100644 --- a/src/libs/actions/IOU/Hold.ts +++ b/src/libs/actions/IOU/Hold.ts @@ -58,6 +58,7 @@ function putOnHold( currentUserAccountID: number, transactionViolations: OnyxEntry, isTrackIntentUser: boolean | undefined, + delegateAccountID: number | undefined, ancestors: Ancestor[] = [], ) { const allTransactions = getAllTransactions(); @@ -65,8 +66,8 @@ function putOnHold( const currentTime = DateUtils.getDBTime(); const reportID = initialReportID ?? generateReportID(); - const createdReportAction = buildOptimisticHoldReportAction(currentTime); - const createdReportActionComment = buildOptimisticHoldReportActionComment(comment, DateUtils.addMillisecondsFromDateTime(currentTime, 1)); + const createdReportAction = buildOptimisticHoldReportAction(delegateAccountID, currentTime); + const createdReportActionComment = buildOptimisticHoldReportActionComment(comment, delegateAccountID, DateUtils.addMillisecondsFromDateTime(currentTime, 1)); const newViolation = {name: CONST.VIOLATIONS.HOLD, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true}; const updatedViolations = [...(transactionViolations ?? []), newViolation]; const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; @@ -349,12 +350,13 @@ function putTransactionsOnHold( currentUserAccountID: number, allTransactionViolations: OnyxCollection, isTrackIntentUser: boolean | undefined, + delegateAccountID: number | undefined, ancestors: Ancestor[] = [], ) { for (const transactionID of transactionsID) { const {childReportID} = getIOUActionForReportID(reportID, transactionID) ?? {}; const transactionViolations = allTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]; - putOnHold(transactionID, comment, childReportID, isOffline, currentUserLogin, currentUserAccountID, transactionViolations, isTrackIntentUser, ancestors); + putOnHold(transactionID, comment, childReportID, isOffline, currentUserLogin, currentUserAccountID, transactionViolations, isTrackIntentUser, delegateAccountID, ancestors); } } @@ -370,11 +372,12 @@ function unholdRequest( currentUserAccountID: number, transactionViolations: OnyxEntry, isTrackIntentUser: boolean | undefined, + delegateAccountID: number | undefined, ) { const allTransactions = getAllTransactions(); const allReports = getAllReports(); - const createdReportAction = buildOptimisticUnHoldReportAction(); + const createdReportAction = buildOptimisticUnHoldReportAction(delegateAccountID); const updatedTransactionViolations = transactionViolations?.filter((violation) => violation.name !== CONST.VIOLATIONS.HOLD) ?? []; const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index 6c4ef8590a13..7fa89c256441 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -206,9 +206,9 @@ function prepareRejectMoneyRequestData({ // Create system messages in both expense report and expense thread // The "rejected this expense" action should come before the reject comment const baseTimestamp = DateUtils.getDBTime(); - const optimisticRejectReportAction = buildOptimisticRejectReportAction(baseTimestamp); + const optimisticRejectReportAction = buildOptimisticRejectReportAction(delegateAccountID, baseTimestamp); const parsedComment = getParsedComment(comment); - const optimisticRejectReportActionComment = buildOptimisticRejectReportActionComment(comment, DateUtils.addMillisecondsFromDateTime(baseTimestamp, 1)); + const optimisticRejectReportActionComment = buildOptimisticRejectReportActionComment(comment, delegateAccountID, DateUtils.addMillisecondsFromDateTime(baseTimestamp, 1)); let movedTransactionAction; // Build successData and failureData to prevent duplication @@ -1041,17 +1041,26 @@ function rejectExpenseReport( currentUserDisplayName: string | undefined, currentUserAvatarSource: AvatarSource | undefined, isTrackIntentUser: boolean | undefined, + delegateAccountID: number | undefined, ) { const {reportID} = report; const isRejectToSubmitter = targetAccountID === report.ownerAccountID; const baseTimestamp = DateUtils.getDBTime(); - const optimisticRejectAction = buildOptimisticReportLevelRejectAction(isRejectToSubmitter, currentUserAccountID, currentUserDisplayName, currentUserAvatarSource, baseTimestamp); + const optimisticRejectAction = buildOptimisticReportLevelRejectAction( + isRejectToSubmitter, + currentUserAccountID, + currentUserDisplayName, + currentUserAvatarSource, + delegateAccountID, + baseTimestamp, + ); const parsedComment = getParsedComment(comment); const optimisticCommentAction = buildOptimisticReportLevelRejectCommentAction( parsedComment, currentUserAccountID, currentUserDisplayName, currentUserAvatarSource, + delegateAccountID, DateUtils.addMillisecondsFromDateTime(baseTimestamp, 1), ); diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 6ecef773055c..104ee10ba217 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -459,6 +459,7 @@ type MergeReportsProps = { isTrackIntentUser: boolean | undefined; personalPolicyOutputCurrency: string | undefined; selfDMReportActions: OnyxEntry; + delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; }; @@ -6492,6 +6493,7 @@ type DeleteAppReportProps = { reportTransactions: Record; allTransactionViolations: OnyxCollection; bankAccountList: OnyxEntry; + delegateAccountID: number | undefined; hash?: number; }; @@ -6612,6 +6614,7 @@ function deleteAppReport({ reportTransactions, allTransactionViolations, bankAccountList, + delegateAccountID, hash, }: DeleteAppReportProps) { if (!report?.reportID) { @@ -6780,7 +6783,7 @@ function deleteAppReport({ ); if (isOnHold(transaction)) { - const unHoldAction = buildOptimisticUnHoldReportAction(); + const unHoldAction = buildOptimisticUnHoldReportAction(delegateAccountID); optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${childReportID}`, @@ -8290,6 +8293,7 @@ function mergeReports({ isTrackIntentUser, personalPolicyOutputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }: MergeReportsProps) { const reports = allReportsParam ?? allReports; @@ -8319,6 +8323,7 @@ function mergeReports({ isTrackIntentUser, personalPolicyOutputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 2b3832a69dbb..fef71a17de51 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -833,6 +833,7 @@ type ChangeTransactionsReportProps = { isTrackIntentUser: boolean | undefined; personalPolicyOutputCurrency: string | undefined; selfDMReportActions: OnyxEntry; + delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; }; @@ -852,6 +853,7 @@ function getChangeTransactionsReportOnyxData({ isTrackIntentUser, personalPolicyOutputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }: ChangeTransactionsReportProps) { const reports = allReportsParam ?? allReports; @@ -1669,7 +1671,7 @@ function getChangeTransactionsReportOnyxData({ // Build unhold report action only when moving to unreported (self DM) report if (isUnreported && isOnHold(transaction)) { - const unHoldAction = buildOptimisticUnHoldReportAction(); + const unHoldAction = buildOptimisticUnHoldReportAction(delegateAccountID); optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID}`, diff --git a/src/pages/DynamicNewReportWorkspaceSelectionPage.tsx b/src/pages/DynamicNewReportWorkspaceSelectionPage.tsx index 7adcf8af51c0..8cf322c6b889 100644 --- a/src/pages/DynamicNewReportWorkspaceSelectionPage.tsx +++ b/src/pages/DynamicNewReportWorkspaceSelectionPage.tsx @@ -12,6 +12,7 @@ import useCreateNewReport from '@hooks/useCreateNewReport'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDebouncedState from '@hooks/useDebouncedState'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import {useIsAppLoadPending} from '@hooks/useInFlightRequests'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; @@ -90,6 +91,7 @@ function DynamicNewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelec const [selfDMReportID] = useOnyx(ONYXKEYS.SELF_DM_REPORT_ID); const [selfDMReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${getNonEmptyStringOnyxID(selfDMReportID)}`); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const personalPolicy = usePersonalPolicy(); const {getCurrencyDecimals} = useCurrencyListActions(); @@ -145,6 +147,7 @@ function DynamicNewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelec isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); diff --git a/src/pages/RejectExpenseReportPage.tsx b/src/pages/RejectExpenseReportPage.tsx index 9806b348ab66..d5c92e1e4192 100644 --- a/src/pages/RejectExpenseReportPage.tsx +++ b/src/pages/RejectExpenseReportPage.tsx @@ -12,6 +12,7 @@ import TextInput from '@components/TextInput'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -80,6 +81,7 @@ function RejectExpenseReportPage({route}: RejectExpenseReportPageProps) { const styles = useThemeStyles(); const {inputCallbackRef} = useAutoFocusInput(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(reportID)}`); const [lastForwardedActorAccountID] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${getNonEmptyStringOnyxID(reportID)}`, {selector: lastForwardedActorAccountIDSelector}); @@ -164,6 +166,7 @@ function RejectExpenseReportPage({route}: RejectExpenseReportPageProps) { currentUserPersonalDetails?.displayName, currentUserPersonalDetails?.avatar, isTrackIntentUser, + delegateAccountID, ); Navigation.goBack(); }; diff --git a/src/pages/Search/SearchHoldReasonPage.tsx b/src/pages/Search/SearchHoldReasonPage.tsx index 0a2773c8be19..1303de3f79b0 100644 --- a/src/pages/Search/SearchHoldReasonPage.tsx +++ b/src/pages/Search/SearchHoldReasonPage.tsx @@ -4,6 +4,7 @@ import {useSearchSelectionActions, useSearchSelectionContext} from '@components/ import useAncestors from '@hooks/useAncestors'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -41,6 +42,7 @@ function SearchHoldReasonPage({route}: SearchHoldReasonPageProps) { const {selectedTransactionIDs, selectedTransactions} = useSearchSelectionContext(); const {clearSelectedTransactions} = useSearchSelectionActions(); const {accountID: currentUserAccountID, login: currentUserLogin} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const relevantTransactionIDs = useMemo(() => (isBulkHold ? selectedTransactionIDs : Object.keys(selectedTransactions)), [isBulkHold, selectedTransactionIDs, selectedTransactions]); @@ -72,6 +74,7 @@ function SearchHoldReasonPage({route}: SearchHoldReasonPageProps) { currentUserAccountID, selectedTransactionViolations, isTrackIntentUser, + delegateAccountID, ancestors, ); clearSelectedTransactions(true); @@ -89,6 +92,7 @@ function SearchHoldReasonPage({route}: SearchHoldReasonPageProps) { currentUserAccountID, transactionViolations, isTrackIntentUser, + delegateAccountID, ancestors, ); } @@ -111,6 +115,7 @@ function SearchHoldReasonPage({route}: SearchHoldReasonPageProps) { currentUserAccountID, selectedTransactionViolations, isTrackIntentUser, + delegateAccountID, ], ); diff --git a/src/pages/Search/SearchTransactionsChangeReport.tsx b/src/pages/Search/SearchTransactionsChangeReport.tsx index d8d06ae4252d..ca8fc9df514b 100644 --- a/src/pages/Search/SearchTransactionsChangeReport.tsx +++ b/src/pages/Search/SearchTransactionsChangeReport.tsx @@ -4,6 +4,7 @@ import type {ListItem} from '@components/SelectionList/types'; import useConditionalCreateEmptyReportConfirmation from '@hooks/useConditionalCreateEmptyReportConfirmation'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useHasPerDiemTransactions from '@hooks/useHasPerDiemTransactions'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; @@ -38,6 +39,7 @@ type TransactionGroupListItem = ListItem & { function SearchTransactionsChangeReport() { const {selectedTransactions} = useSearchSelectionContext(); + const delegateAccountID = useDelegateAccountID(); const {clearSelectedTransactions} = useSearchSelectionActions(); const {currentSearchResults} = useSearchResultsContext(); const selectedTransactionsKeys = useMemo(() => Object.keys(selectedTransactions), [selectedTransactions]); @@ -179,6 +181,7 @@ function SearchTransactionsChangeReport() { isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); clearSelectedTransactions(); @@ -259,6 +262,7 @@ function SearchTransactionsChangeReport() { isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); Navigation.goBack(undefined, {afterTransition: clearSelectedTransactions}); @@ -282,6 +286,7 @@ function SearchTransactionsChangeReport() { isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); clearSelectedTransactions(); diff --git a/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx index b60f60963d23..8ab7378b8a83 100644 --- a/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx @@ -12,6 +12,7 @@ import Text from '@components/Text'; import {useWideRHPState} from '@components/WideRHPContextProvider'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -99,6 +100,7 @@ function DynamicConfirmationPage() { const [mergeErrorMessage, setMergeErrorMessage] = useState(''); const currentUserAccountID = currentUserPersonalDetails.accountID; const currentUserLogin = currentUserPersonalDetails?.login; + const delegateAccountID = useDelegateAccountID(); const childReportID = reportAction?.childReportID; const handleMergeDuplicates = useCallback(() => { @@ -124,9 +126,9 @@ function DynamicConfirmationPage() { }, [childReportID, transactionsMergeParams, taxData, currentUserAccountID, currentUserLogin, isSuperWideRHPDisplayed, allTransactionViolations, allReportActions]); const handleResolveDuplicates = useCallback(() => { - resolveDuplicates({...transactionsMergeParams, ...taxData, transactionThreadReportIDMap, allTransactionViolations, allReportActionsList: allReportActions}); + resolveDuplicates({...transactionsMergeParams, ...taxData, transactionThreadReportIDMap, allTransactionViolations, allReportActionsList: allReportActions, delegateAccountID}); Navigation.dismissToSuperWideRHP(); - }, [transactionsMergeParams, taxData, transactionThreadReportIDMap, allTransactionViolations, allReportActions]); + }, [transactionsMergeParams, taxData, transactionThreadReportIDMap, allTransactionViolations, allReportActions, delegateAccountID]); const contextMenuStateValue = useMemo( () => ({ diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index fa1bfcccaa54..146e04b9bea3 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -655,7 +655,17 @@ const ContextMenuActions: ContextMenuAction[] = [ }, onPress: ( closePopover, - {moneyRequestAction, iouTransaction, iouTransactionViolations, isDelegateAccessRestricted, showDelegateNoAccessModal, isOffline, currentUserPersonalDetails, isTrackIntentUser}, + { + moneyRequestAction, + iouTransaction, + iouTransactionViolations, + isDelegateAccessRestricted, + showDelegateNoAccessModal, + isOffline, + currentUserPersonalDetails, + isTrackIntentUser, + delegateAccountID, + }, ) => { if (isDelegateAccessRestricted) { hideContextMenu(false, showDelegateNoAccessModal); @@ -672,6 +682,7 @@ const ContextMenuActions: ContextMenuAction[] = [ currentUserPersonalDetails.accountID, iouTransactionViolations, isTrackIntentUser, + delegateAccountID, ), ); return; @@ -686,6 +697,7 @@ const ContextMenuActions: ContextMenuAction[] = [ currentUserPersonalDetails.accountID, iouTransactionViolations, isTrackIntentUser, + delegateAccountID, ); }, getDescription: () => {}, @@ -704,7 +716,17 @@ const ContextMenuActions: ContextMenuAction[] = [ }, onPress: ( closePopover, - {moneyRequestAction, iouTransaction, iouTransactionViolations, isDelegateAccessRestricted, showDelegateNoAccessModal, isOffline, currentUserPersonalDetails, isTrackIntentUser}, + { + moneyRequestAction, + iouTransaction, + iouTransactionViolations, + isDelegateAccessRestricted, + showDelegateNoAccessModal, + isOffline, + currentUserPersonalDetails, + isTrackIntentUser, + delegateAccountID, + }, ) => { if (isDelegateAccessRestricted) { hideContextMenu(false, showDelegateNoAccessModal); @@ -721,6 +743,7 @@ const ContextMenuActions: ContextMenuAction[] = [ currentUserPersonalDetails.accountID, iouTransactionViolations, isTrackIntentUser, + delegateAccountID, ), ); return; @@ -735,6 +758,7 @@ const ContextMenuActions: ContextMenuAction[] = [ currentUserPersonalDetails.accountID, iouTransactionViolations, isTrackIntentUser, + delegateAccountID, ); }, getDescription: () => {}, diff --git a/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx index b14437689875..23248f6c5e83 100644 --- a/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -6,6 +6,7 @@ import {useSearchQueryContext} from '@components/Search/SearchContext'; import useAncestors from '@hooks/useAncestors'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDeleteTransactions from '@hooks/useDeleteTransactions'; import useDuplicateTransactionsAndViolations from '@hooks/useDuplicateTransactionsAndViolations'; import useGetIOUReportFromReportAction from '@hooks/useGetIOUReportFromReportAction'; @@ -85,6 +86,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro }); const instanceIDRef = useRef(''); const {email, accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [isPopoverVisible, setIsPopoverVisible] = useState(false); // UI-thread timer driving the delayed hide. https://github.com/Expensify/App/issues/89069 @@ -417,6 +419,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro reportTransactions, allTransactionViolations, bankAccountList, + delegateAccountID, hash: currentSearchHash, }); } else if (reportAction) { @@ -453,6 +456,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro isChatIOUReportArchived, allTransactionViolations, currentUserAccountID, + delegateAccountID, deleteTransactions, currentSearchHash, email, diff --git a/src/pages/iou/HoldReasonPage.tsx b/src/pages/iou/HoldReasonPage.tsx index dd9396be825a..bf53806b33e7 100644 --- a/src/pages/iou/HoldReasonPage.tsx +++ b/src/pages/iou/HoldReasonPage.tsx @@ -3,6 +3,7 @@ import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import useAncestors from '@hooks/useAncestors'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -37,6 +38,7 @@ type HoldReasonPageProps = function HoldReasonPage({route}: HoldReasonPageProps) { const {translate} = useLocalize(); const {accountID: currentUserAccountID, login: currentUserLogin} = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const {transactionID, reportID, backTo} = route.params; @@ -73,7 +75,7 @@ function HoldReasonPage({route}: HoldReasonPageProps) { return; } - putOnHold(transactionID, values.comment, reportID, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser, ancestors); + putOnHold(transactionID, values.comment, reportID, isOffline, currentUserLogin ?? '', currentUserAccountID, transactionViolations, isTrackIntentUser, delegateAccountID, ancestors); Navigation.goBack(backTo); }; diff --git a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx index 9e432f26c692..5db99887fd7b 100644 --- a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx +++ b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx @@ -5,6 +5,7 @@ import type {ListItem} from '@components/SelectionList/types'; import useConditionalCreateEmptyReportConfirmation from '@hooks/useConditionalCreateEmptyReportConfirmation'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useHasPerDiemTransactions from '@hooks/useHasPerDiemTransactions'; import useOnyx from '@hooks/useOnyx'; @@ -59,6 +60,7 @@ function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) const {isBetaEnabled} = usePermissions(); const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const personalPolicy = usePersonalPolicy(); const [personalPolicyID] = useOnyx(ONYXKEYS.PERSONAL_POLICY_ID); const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END); @@ -118,6 +120,7 @@ function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); turnOffMobileSelectionMode(); @@ -145,6 +148,7 @@ function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) isTrackIntentUser, personalPolicyOutputCurrency: personalPolicy?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); if (shouldTurnOffSelectionMode) { diff --git a/src/pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts b/src/pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts index db6e48dfeb69..2c07d7aa949b 100644 --- a/src/pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts +++ b/src/pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts @@ -2,6 +2,7 @@ import {useSearchSelectionActions} from '@components/Search/SearchContext'; import type {ListItem} from '@components/SelectionList/types'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; @@ -116,6 +117,7 @@ function useReportSelectionActions({ const {isBetaEnabled} = usePermissions(); const isNewManualExpenseFlowEnabled = isBetaEnabled(CONST.BETAS.NEW_MANUAL_EXPENSE_FLOW); const [isTrackIntentUser] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {selector: isTrackIntentUserSelector}); + const delegateAccountID = useDelegateAccountID(); const {getCurrencyDecimals} = useCurrencyListActions(); const targetTransactionIDs = transaction?.transactionID ? [transaction.transactionID] : []; @@ -220,6 +222,7 @@ function useReportSelectionActions({ isTrackIntentUser, personalPolicyOutputCurrency: allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${personalPolicyID}`]?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); removeTransaction(transaction.transactionID); @@ -248,6 +251,7 @@ function useReportSelectionActions({ isTrackIntentUser, personalPolicyOutputCurrency: allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${personalPolicyID}`]?.outputCurrency, selfDMReportActions, + delegateAccountID, getCurrencyDecimals, }); removeTransaction(transaction.transactionID); diff --git a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx index 6da83761fda5..bf08a754a77b 100644 --- a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx +++ b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx @@ -11,6 +11,7 @@ import useActivePolicy from '@hooks/useActivePolicy'; import useCreateNewReport from '@hooks/useCreateNewReport'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useHasActiveAdminPolicies from '@hooks/useHasActiveAdminPolicies'; import useLastWorkspaceNumber from '@hooks/useLastWorkspaceNumber'; import useLocalize from '@hooks/useLocalize'; @@ -63,6 +64,7 @@ function IOURequestStepUpgrade({ const {translate} = useLocalize(); const {isOffline} = useNetwork(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const personalDetails = usePersonalDetails(); const activePolicy = useActivePolicy(); const personalPolicy = usePersonalPolicy(); @@ -160,6 +162,7 @@ function IOURequestStepUpgrade({ isTrackIntentUser, // Expenses move to the upgraded workspace (newPolicy), whose currency drives any distance calculation, so the personal-policy currency is never read here. personalPolicyOutputCurrency: undefined, + delegateAccountID, getCurrencyDecimals, }); @@ -267,6 +270,7 @@ function IOURequestStepUpgrade({ allReports, selfDMReportActions, isTrackIntentUser, + delegateAccountID, getCurrencyDecimals, ]); diff --git a/tests/actions/IOUTest/DuplicateTest.ts b/tests/actions/IOUTest/DuplicateTest.ts index d412743360f1..448ddcfc356d 100644 --- a/tests/actions/IOUTest/DuplicateTest.ts +++ b/tests/actions/IOUTest/DuplicateTest.ts @@ -947,6 +947,7 @@ describe('actions/Duplicate', () => { [duplicate1ID]: childReportID1, [duplicate2ID]: childReportID2, }, + delegateAccountID: undefined, }; // When: Call resolveDuplicates @@ -1049,6 +1050,7 @@ describe('actions/Duplicate', () => { receiptID: 123, reportID: 'report123', transactionThreadReportIDMap: {}, + delegateAccountID: undefined, }; // When: Call resolveDuplicates with undefined transactionID @@ -1092,6 +1094,7 @@ describe('actions/Duplicate', () => { receiptID: 123, reportID, transactionThreadReportIDMap: {}, + delegateAccountID: undefined, }; // When: Call resolveDuplicates with empty duplicate list @@ -1160,6 +1163,7 @@ describe('actions/Duplicate', () => { receiptID: 123, reportID, transactionThreadReportIDMap: {}, + delegateAccountID: undefined, }; // When: Call resolveDuplicates without matching IOU actions @@ -1236,6 +1240,7 @@ describe('actions/Duplicate', () => { receiptID: 123, reportID, transactionThreadReportIDMap: {}, + delegateAccountID: undefined, }; // When: Call resolveDuplicates while the duplicate has no thread @@ -1315,6 +1320,7 @@ describe('actions/Duplicate', () => { transactionThreadReportIDMap: { [duplicate1ID]: childReportID1, }, + delegateAccountID: undefined, }; // When: Call resolveDuplicates @@ -1385,6 +1391,7 @@ describe('actions/Duplicate', () => { transactionThreadReportIDMap: { [duplicate1ID]: childReportID1, }, + delegateAccountID: undefined, }; // When: Call resolveDuplicates while the kept transaction has no thread @@ -1467,6 +1474,7 @@ describe('actions/Duplicate', () => { transactionThreadReportIDMap: { [crossReportDuplicateID]: childReportIDCross, }, + delegateAccountID: undefined, }; // When: Call resolveDuplicates with cross-report duplicates @@ -2533,6 +2541,7 @@ describe('actions/Duplicate', () => { }, allTransactionViolations: {}, allReportActionsList, + delegateAccountID: undefined, }); return waitForBatchedUpdates(); }) diff --git a/tests/actions/IOUTest/HoldTest.ts b/tests/actions/IOUTest/HoldTest.ts index 4271a73c7277..6ee89bb9ab13 100644 --- a/tests/actions/IOUTest/HoldTest.ts +++ b/tests/actions/IOUTest/HoldTest.ts @@ -133,7 +133,7 @@ describe('actions/IOU/Hold', () => { .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { // When an expense is put on hold - putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -195,7 +195,7 @@ describe('actions/IOU/Hold', () => { .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { // When an expense is put on hold without existing transaction thread (undefined initialReportID) - putOnHold(transaction.transactionID, comment, undefined, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, undefined, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -275,7 +275,17 @@ describe('actions/IOU/Hold', () => { .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { // When multiple transactions are put on hold - putTransactionsOnHold([transaction1.transactionID, transaction2.transactionID], comment, iouReport.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putTransactionsOnHold( + [transaction1.transactionID, transaction2.transactionID], + comment, + iouReport.reportID, + false, + RORY_EMAIL, + RORY_ACCOUNT_ID, + undefined, + false, + undefined, + ); return waitForBatchedUpdates(); }) .then(() => { @@ -369,7 +379,17 @@ describe('actions/IOU/Hold', () => { .then(() => { jest.mocked(Navigation.setNavigationActionToMicrotaskQueue).mockClear(); // When transactions are put on hold while offline (isOffline: true) - putTransactionsOnHold([transaction1.transactionID, transaction2.transactionID], comment, iouReport.reportID, true, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putTransactionsOnHold( + [transaction1.transactionID, transaction2.transactionID], + comment, + iouReport.reportID, + true, + RORY_EMAIL, + RORY_ACCOUNT_ID, + undefined, + false, + undefined, + ); return waitForBatchedUpdates(); }) .then(() => { @@ -415,7 +435,7 @@ describe('actions/IOU/Hold', () => { .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { jest.mocked(Navigation.setNavigationActionToMicrotaskQueue).mockClear(); - putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -423,7 +443,7 @@ describe('actions/IOU/Hold', () => { expect(Navigation.setNavigationActionToMicrotaskQueue).toHaveBeenCalledTimes(1); jest.mocked(Navigation.setNavigationActionToMicrotaskQueue).mockClear(); - putOnHold(transaction.transactionID, comment, transactionThread.reportID, true, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, transactionThread.reportID, true, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -476,7 +496,7 @@ describe('actions/IOU/Hold', () => { return waitForBatchedUpdates() .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { - putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -490,6 +510,7 @@ describe('actions/IOU/Hold', () => { RORY_ACCOUNT_ID, [{name: CONST.VIOLATIONS.HOLD, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true}], false, + undefined, ); return waitForBatchedUpdates(); }) @@ -559,7 +580,7 @@ describe('actions/IOU/Hold', () => { return waitForBatchedUpdates() .then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { - putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false); + putOnHold(transaction.transactionID, comment, transactionThread.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined); return waitForBatchedUpdates(); }) .then(() => { @@ -574,6 +595,7 @@ describe('actions/IOU/Hold', () => { RORY_ACCOUNT_ID, [{name: CONST.VIOLATIONS.HOLD, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true}], false, + undefined, ); return waitForBatchedUpdates(); }) diff --git a/tests/actions/IOUTest/PayMoneyRequestTest.ts b/tests/actions/IOUTest/PayMoneyRequestTest.ts index a030fa24ef8f..2e1bc9dd3ebd 100644 --- a/tests/actions/IOUTest/PayMoneyRequestTest.ts +++ b/tests/actions/IOUTest/PayMoneyRequestTest.ts @@ -857,7 +857,7 @@ describe('actions/IOU/PayMoneyRequest', () => { return waitForBatchedUpdates() .then(() => Onyx.multiSet({...transactionCollectionDataSet, ...actionCollectionDataSet})) .then(() => { - putOnHold(transaction1.transactionID, 'comment', iouReport.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, []); + putOnHold(transaction1.transactionID, 'comment', iouReport.reportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined, []); return waitForBatchedUpdates(); }) .then(() => { diff --git a/tests/actions/IOUTest/RejectMoneyRequestTest.ts b/tests/actions/IOUTest/RejectMoneyRequestTest.ts index 7a3774da25b2..94021fc8ced0 100644 --- a/tests/actions/IOUTest/RejectMoneyRequestTest.ts +++ b/tests/actions/IOUTest/RejectMoneyRequestTest.ts @@ -377,7 +377,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { // eslint-disable-next-line rulesdir/no-multiple-api-calls const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn()); - rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false); + rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false, undefined); await waitForBatchedUpdates(); expect(writeSpy).toHaveBeenCalledWith( @@ -398,7 +398,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { // eslint-disable-next-line rulesdir/no-multiple-api-calls const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn()); - rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, markdownComment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false); + rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, markdownComment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false, undefined); await waitForBatchedUpdates(); expect(writeSpy).toHaveBeenCalledWith( @@ -412,7 +412,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { }); it('should optimistically update the report when rejecting to submitter', async () => { - rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false); + rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false, undefined); await waitForBatchedUpdates(); const updatedReport = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`); @@ -422,7 +422,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { }); it('should optimistically update the report when rejecting to a previous approver', async () => { - rejectExpenseReport(expenseReport, APPROVER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false); + rejectExpenseReport(expenseReport, APPROVER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false, undefined); await waitForBatchedUpdates(); const updatedReport = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`); @@ -432,7 +432,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { }); it('should create optimistic report actions with passed user details', async () => { - rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false); + rejectExpenseReport(expenseReport, SUBMITTER_ACCOUNT_ID, comment, TEST_USER_ACCOUNT_ID, CURRENT_USER_DISPLAY_NAME, CURRENT_USER_AVATAR, false, undefined); await waitForBatchedUpdates(); const reportActions = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`); diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 126eae7f0e36..1fc6fd48ce4f 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -4893,7 +4893,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { // Put the expense on hold if (originalTransactionID && transactionThreadReportID) { - putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, []); + putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined, []); } await waitForBatchedUpdates(); @@ -5756,7 +5756,7 @@ describe('updateSplitTransactions', () => { // Put the original transaction on hold before splitting it. const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`]; const ancestors = getAncestors(transactionThreadReport, allReports, {}, allReportActions); - putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, ancestors); + putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined, ancestors); await waitForBatchedUpdates(); const iouAction = getIOUActionForReportID(expenseReport?.reportID, originalTransactionID); @@ -5923,7 +5923,7 @@ describe('updateSplitTransactions', () => { // Put the split transaction 1 on hold before reverting it const {allReports: allReports2, allReportActions: allReportActions2} = await getCollections(); const ancestors2 = getAncestors(split1ThreadReport, allReports2, {}, allReportActions2); - putOnHold(splitTransactionID1, 'Test hold reason', split1ThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, ancestors2); + putOnHold(splitTransactionID1, 'Test hold reason', split1ThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, undefined, false, undefined, ancestors2); await waitForBatchedUpdates(); const iouAction = getIOUActionForReportID(expenseReport?.reportID, splitTransactionID1); diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 560bd5d90021..c7bdf433270f 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -3349,6 +3349,7 @@ describe('actions/Report', () => { reportTransactions: {}, allTransactionViolations: {}, bankAccountList: {}, + delegateAccountID: undefined, }); await waitForBatchedUpdates(); @@ -3461,6 +3462,7 @@ describe('actions/Report', () => { }, allTransactionViolations: {}, bankAccountList: {}, + delegateAccountID: undefined, }); await waitForBatchedUpdates(); @@ -3533,6 +3535,7 @@ describe('actions/Report', () => { reportTransactions: {}, allTransactionViolations: {}, bankAccountList: {}, + delegateAccountID: undefined, }); await waitForBatchedUpdates(); @@ -9631,6 +9634,7 @@ describe('actions/Report', () => { isTrackIntentUser: false, personalPolicyOutputCurrency: undefined, selfDMReportActions: undefined, + delegateAccountID: undefined, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, }); await waitForBatchedUpdates(); @@ -9699,6 +9703,7 @@ describe('actions/Report', () => { isTrackIntentUser: false, personalPolicyOutputCurrency: undefined, selfDMReportActions: undefined, + delegateAccountID: undefined, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, }); await waitForBatchedUpdates(); @@ -9757,6 +9762,7 @@ describe('actions/Report', () => { isTrackIntentUser: false, personalPolicyOutputCurrency: undefined, selfDMReportActions: undefined, + delegateAccountID: undefined, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, }); await waitForBatchedUpdates(); diff --git a/tests/actions/TransactionTest.ts b/tests/actions/TransactionTest.ts index 661b1dae411b..817d1859efe9 100644 --- a/tests/actions/TransactionTest.ts +++ b/tests/actions/TransactionTest.ts @@ -41,7 +41,7 @@ import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; type LegacyChangeTransactionsReportProps = Omit< Parameters[0], - 'transactions' | 'allTransactionViolation' | 'personalPolicyOutputCurrency' | 'selfDMReportActions' | 'getCurrencyDecimals' + 'transactions' | 'allTransactionViolation' | 'personalPolicyOutputCurrency' | 'selfDMReportActions' | 'delegateAccountID' | 'getCurrencyDecimals' > & { allTransactions: OnyxCollection; transactionViolations: Parameters[0]['allTransactionViolation']; @@ -58,6 +58,7 @@ function changeTransactionsReport({allTransactions, transactionIDs, transactionV allTransactionViolation: transactionViolations, personalPolicyOutputCurrency, selfDMReportActions, + delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, ...rest, }); @@ -1219,7 +1220,7 @@ describe('actions/Transaction', () => { // Put the expense on hold if (originalTransactionID && transactionThreadReportID) { - putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, [], false); + putOnHold(originalTransactionID, 'Test hold reason', transactionThreadReportID, false, RORY_EMAIL, RORY_ACCOUNT_ID, [], false, undefined); } await waitForBatchedUpdates(); diff --git a/tests/ui/components/BaseReportActionContextMenuTest.tsx b/tests/ui/components/BaseReportActionContextMenuTest.tsx index 1904ccd7b259..c76dc0f58797 100644 --- a/tests/ui/components/BaseReportActionContextMenuTest.tsx +++ b/tests/ui/components/BaseReportActionContextMenuTest.tsx @@ -408,6 +408,7 @@ describe('BaseReportActionContextMenu hold/unhold action', () => { currentUserAccountID, undefined, false, + undefined, ); }); }); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 626b2589af95..3de8f51eee48 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -40,10 +40,17 @@ import { buildOptimisticEmptyReport, buildOptimisticExpenseReport, buildOptimisticGroupChatReport, + buildOptimisticHoldReportAction, + buildOptimisticHoldReportActionComment, buildOptimisticInvoiceReport, buildOptimisticIOUReportAction, buildOptimisticMoneyRequestEntities, + buildOptimisticRejectReportAction, + buildOptimisticRejectReportActionComment, + buildOptimisticReportLevelRejectAction, + buildOptimisticReportLevelRejectCommentAction, buildOptimisticReportPreview, + buildOptimisticUnHoldReportAction, buildOptimisticWorkspaceChats, buildParticipantsFromAccountIDs, buildTransactionThread, @@ -5230,7 +5237,7 @@ describe('ReportUtils', () => { canUnholdRequest: false, }); - putOnHold(expenseTransaction.transactionID, 'hold', transactionThreadReport.reportID, false, currentUserEmail, currentUserAccountID, undefined, false, []); + putOnHold(expenseTransaction.transactionID, 'hold', transactionThreadReport.reportID, false, currentUserEmail, currentUserAccountID, undefined, false, undefined, []); await waitForBatchedUpdates(); const expenseReportUpdated = await new Promise>((resolve) => { @@ -5472,7 +5479,7 @@ describe('ReportUtils', () => { const unholdRequestSpy = jest.spyOn(HoldUtils, 'unholdRequest').mockImplementation(() => undefined); // When changeMoneyRequestHoldStatus is called - changeMoneyRequestHoldStatus(reportAction, iouTransaction, false, currentUserEmail, currentUserAccountID, undefined, false); + changeMoneyRequestHoldStatus(reportAction, iouTransaction, false, currentUserEmail, currentUserAccountID, undefined, false, undefined); // Then unholdRequest should be called with the correct parameters and navigation should not be called expect(unholdRequestSpy).toHaveBeenCalledWith( @@ -5484,6 +5491,7 @@ describe('ReportUtils', () => { currentUserAccountID, undefined, false, + undefined, ); expect(Navigation.navigate).not.toHaveBeenCalled(); }); @@ -5527,7 +5535,7 @@ describe('ReportUtils', () => { await waitForBatchedUpdates(); // When changeMoneyRequestHoldStatus is called - changeMoneyRequestHoldStatus(reportAction, iouTransaction, false, currentUserEmail, currentUserAccountID, undefined, false); + changeMoneyRequestHoldStatus(reportAction, iouTransaction, false, currentUserEmail, currentUserAccountID, undefined, false, undefined); // Then navigation should be called with the correct parameters expect(Navigation.navigate).toHaveBeenCalledWith( @@ -21975,6 +21983,45 @@ describe('areAllRequestsBeingSmartScanned', () => { }); }); +describe('hold/unhold/reject optimistic builders set delegateAccountID', () => { + const DELEGATE_ACCOUNT_ID = 424242; + + it('buildOptimisticHoldReportAction sets the passed delegateAccountID', () => { + expect(buildOptimisticHoldReportAction(DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticHoldReportAction(undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticHoldReportActionComment sets the passed delegateAccountID', () => { + expect(buildOptimisticHoldReportActionComment('hold reason', DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticHoldReportActionComment('hold reason', undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticUnHoldReportAction sets the passed delegateAccountID', () => { + expect(buildOptimisticUnHoldReportAction(DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticUnHoldReportAction(undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticRejectReportAction sets the passed delegateAccountID', () => { + expect(buildOptimisticRejectReportAction(DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticRejectReportAction(undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticRejectReportActionComment sets the passed delegateAccountID', () => { + expect(buildOptimisticRejectReportActionComment('reject reason', DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticRejectReportActionComment('reject reason', undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticReportLevelRejectAction sets the passed delegateAccountID', () => { + expect(buildOptimisticReportLevelRejectAction(true, currentUserAccountID, 'Test User', undefined, DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticReportLevelRejectAction(true, currentUserAccountID, 'Test User', undefined, undefined).delegateAccountID).toBeUndefined(); + }); + + it('buildOptimisticReportLevelRejectCommentAction sets the passed delegateAccountID', () => { + expect(buildOptimisticReportLevelRejectCommentAction('reject reason', currentUserAccountID, 'Test User', undefined, DELEGATE_ACCOUNT_ID).delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + expect(buildOptimisticReportLevelRejectCommentAction('reject reason', currentUserAccountID, 'Test User', undefined, undefined).delegateAccountID).toBeUndefined(); + }); +}); + describe('getInvoiceReceiverPersonalDetail', () => { it('returns the personal detail of the receiver account when the receiver is an individual', () => { const report = {reportID: '1', invoiceReceiver: {type: CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL, accountID: 1}} as Report; diff --git a/tests/unit/TransactionTest.ts b/tests/unit/TransactionTest.ts index c7ed333b88a8..9275c4ceda6e 100644 --- a/tests/unit/TransactionTest.ts +++ b/tests/unit/TransactionTest.ts @@ -35,7 +35,7 @@ import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; type LegacyChangeTransactionsReportProps = Omit< Parameters[0], - 'transactions' | 'allTransactionViolation' | 'personalPolicyOutputCurrency' | 'selfDMReportActions' | 'getCurrencyDecimals' + 'transactions' | 'allTransactionViolation' | 'personalPolicyOutputCurrency' | 'selfDMReportActions' | 'delegateAccountID' | 'getCurrencyDecimals' > & { allTransactions: OnyxCollection; transactionViolations?: OnyxCollection; @@ -60,6 +60,7 @@ function changeTransactionsReport({allTransactions, transactionIDs, transactionV allTransactionViolation: transactionViolations, personalPolicyOutputCurrency, selfDMReportActions: undefined, + delegateAccountID: undefined, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, ...rest, }); diff --git a/tests/unit/hooks/useSelectedTransactionsActions.test.ts b/tests/unit/hooks/useSelectedTransactionsActions.test.ts index eecebaa4e42b..eec76b87fe80 100644 --- a/tests/unit/hooks/useSelectedTransactionsActions.test.ts +++ b/tests/unit/hooks/useSelectedTransactionsActions.test.ts @@ -723,7 +723,7 @@ describe('useSelectedTransactionsActions', () => { unholdOption?.onSelected?.(); - expect(unholdRequest).toHaveBeenCalledWith(transactionID, 'child123', undefined, false, CURRENT_USER_LOGIN, CURRENT_USER_ACCOUNT_ID, undefined, false); + expect(unholdRequest).toHaveBeenCalledWith(transactionID, 'child123', undefined, false, CURRENT_USER_LOGIN, CURRENT_USER_ACCOUNT_ID, undefined, false, undefined); expect(mockClearSelectedTransactions).toHaveBeenCalledWith(true); }); @@ -777,7 +777,7 @@ describe('useSelectedTransactionsActions', () => { unholdOption?.onSelected?.(); - expect(unholdRequest).toHaveBeenCalledWith(transactionID, 'child123', undefined, true, CURRENT_USER_LOGIN, CURRENT_USER_ACCOUNT_ID, undefined, false); + expect(unholdRequest).toHaveBeenCalledWith(transactionID, 'child123', undefined, true, CURRENT_USER_LOGIN, CURRENT_USER_ACCOUNT_ID, undefined, false, undefined); expect(mockClearSelectedTransactions).toHaveBeenCalledWith(true); });