diff --git a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx index 769a1b3512cc..52ef315e6856 100644 --- a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx +++ b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx @@ -417,6 +417,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo amountOwed, ownerBillingGracePeriodEnd, delegateEmail, + ownerLogin: submitterLogin, }); }; diff --git a/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx b/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx index 396af6ffb353..03cd0ed794a9 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx +++ b/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx @@ -15,6 +15,7 @@ import {createTransactionThreadReport} from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import {personalDetailsLoginSelector} from '@src/selectors/PersonalDetails'; import React from 'react'; @@ -31,6 +32,7 @@ function ReviewDuplicatesPrimaryAction({reportID, chatReportID}: SimpleActionPro const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(moneyRequestReport?.ownerAccountID)}); const {transactions: reportTransactionsMap} = useTransactionsAndViolationsForReport(moneyRequestReport?.reportID); const transactions = Object.values(reportTransactionsMap); @@ -48,6 +50,7 @@ function ReviewDuplicatesPrimaryAction({reportID, chatReportID}: SimpleActionPro email ?? '', accountID, moneyRequestReport, + ownerLogin, policy, allTransactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + reportTransaction.transactionID], ), diff --git a/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts b/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts index 6bf77aca7719..b9e4357c2847 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts +++ b/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts @@ -16,6 +16,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {delegateEmailSelector} from '@selectors/Account'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; function useConfirmApproval(reportID: string | undefined, startApprovedAnimation: () => void) { const {accountID, email} = useCurrentUserPersonalDetails(); @@ -33,6 +34,7 @@ function useConfirmApproval(reportID: string | undefined, startApprovedAnimation const [ownerBillingGracePeriodEnd] = useOnyx(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); const [delegateEmail] = useOnyx(ONYXKEYS.ACCOUNT, {selector: delegateEmailSelector}); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(moneyRequestReport?.ownerAccountID)}); const {transactions: reportTransactions} = useTransactionsAndViolationsForReport(moneyRequestReport?.reportID); const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); @@ -63,6 +65,7 @@ function useConfirmApproval(reportID: string | undefined, startApprovedAnimation userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin, full: true, onApproved: startApprovedAnimation, delegateEmail, diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 2cbd5549f863..1e1d2576084b 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -31,6 +31,7 @@ import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; +import {personalDetailsLoginSelector} from '@src/selectors/PersonalDetails'; import type IconAsset from '@src/types/utils/IconAsset'; import type {ReactNode} from 'react'; @@ -60,6 +61,7 @@ type MoneyRequestHeaderProps = { function MoneyRequestHeader({reportID: reportIDProp, onBackButtonPress}: MoneyRequestHeaderProps) { const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportIDProp}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(report?.ownerAccountID)}); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(report?.policyID)}`); const parentReportAction = useParentReportAction(report); @@ -91,7 +93,7 @@ function MoneyRequestHeader({reportID: reportIDProp, onBackButtonPress}: MoneyRe const isOnHold = isOnHoldTransactionUtils(transaction); const isParentReportSettled = isSettledReportUtils(parentReport); - const isDuplicate = !isParentReportSettled && isDuplicateTransactionUtils(transaction, email ?? '', accountID, report, policy, transactionViolations); + const isDuplicate = !isParentReportSettled && isDuplicateTransactionUtils(transaction, email ?? '', accountID, report, ownerLogin, policy, transactionViolations); const hasPendingRTERViolation = hasPendingRTERViolationTransactionUtils(transactionViolations); const shouldShowBrokenConnectionViolation = shouldShowBrokenConnectionViolationTransactionUtils(parentReport, policy, transactionViolations); diff --git a/src/components/MoneyRequestHeaderPrimaryAction.tsx b/src/components/MoneyRequestHeaderPrimaryAction.tsx index 87f506e07c3e..9d14567b94ff 100644 --- a/src/components/MoneyRequestHeaderPrimaryAction.tsx +++ b/src/components/MoneyRequestHeaderPrimaryAction.tsx @@ -27,6 +27,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import React from 'react'; import {View} from 'react-native'; @@ -62,6 +63,7 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc // Per-key Onyx subscriptions const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`); + const [parentOwnerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(parentReport?.ownerAccountID)}); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`); const parentReportAction = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined; @@ -78,7 +80,7 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc const primaryAction = report && parentReport && transaction - ? getTransactionThreadPrimaryAction(currentUserLogin ?? '', accountID, report, parentReport, transaction, transactionViolations, policy, isFromReviewDuplicates) + ? getTransactionThreadPrimaryAction(currentUserLogin ?? '', accountID, report, parentReport, parentOwnerLogin, transaction, transactionViolations, policy, isFromReviewDuplicates) : ''; const renderButton = () => { diff --git a/src/components/MoneyRequestHeaderSecondaryActions.tsx b/src/components/MoneyRequestHeaderSecondaryActions.tsx index 35b8d2d4b0d8..1871e824c634 100644 --- a/src/components/MoneyRequestHeaderSecondaryActions.tsx +++ b/src/components/MoneyRequestHeaderSecondaryActions.tsx @@ -73,6 +73,7 @@ import type {ValueOf} from 'type-fest'; import {useRoute} from '@react-navigation/native'; import {shouldFailAllRequestsSelector} from '@selectors/Network'; import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import {validTransactionDraftsSelector} from '@selectors/TransactionDraft'; import React, {useRef, useState} from 'react'; @@ -128,6 +129,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money // Per-key Onyx subscriptions const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`); + const [parentOwnerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(parentReport?.ownerAccountID)}); const [grandParentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReport?.parentReportID}`); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`); @@ -195,7 +197,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money report && parentReport && transaction && - getTransactionThreadPrimaryAction(currentUserLogin ?? '', accountID, report, parentReport, transaction, transactionViolations, policy, false) + getTransactionThreadPrimaryAction(currentUserLogin ?? '', accountID, report, parentReport, parentOwnerLogin, transaction, transactionViolations, policy, false) ); const activePolicyExpenseChat = getPolicyExpenseChat(accountID, defaultExpensePolicy?.id); const isPerDiemRequestOnNonDefaultWorkspace = isPerDiemRequest(transaction) && defaultExpensePolicy?.id !== policy?.id; diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx index 806b7bae2458..54d66a863add 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx @@ -80,6 +80,7 @@ import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import type {LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, ScrollView as RNScrollView} from 'react-native'; import {findFocusedRoute, useFocusEffect} from '@react-navigation/native'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import {validTransactionDraftIDsSelector} from '@selectors/TransactionDraft'; import isEmpty from 'lodash/isEmpty'; import React, {memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; @@ -106,6 +107,7 @@ function filterTransactionViolations( email: string, accountID: number, report: OnyxTypes.Report, + ownerLogin: string | undefined, policy: OnyxTypes.Policy | undefined, ): OnyxTypes.TransactionViolations { if (!allViolations) { @@ -115,7 +117,7 @@ function filterTransactionViolations( if (!raw?.length) { return EMPTY_VIOLATIONS; } - const filtered = getVisibleTransactionViolations(transaction, raw, email, accountID, report, policy); + const filtered = getVisibleTransactionViolations(transaction, raw, email, accountID, report, ownerLogin, policy); return filtered.length === 0 ? EMPTY_VIOLATIONS : filtered; } @@ -200,6 +202,7 @@ function MoneyRequestReportTransactionList({ const shouldShowBreakdown = shouldShowExpenseReportBreakDown || !!billableTotal || (!!taxTotal && isTaxEnabled); const transactionsWithoutPendingDelete = useMemo(() => transactions.filter((t) => !isTransactionPendingDelete(t)), [transactions]); const currentUserDetails = useCurrentUserPersonalDetails(); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(report?.ownerAccountID)}); const isReportArchived = useReportIsArchived(report?.reportID); const shouldShowAddExpenseButton = canAddTransaction(report, isReportArchived) && isCurrentUserSubmitter(report); const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END); @@ -693,10 +696,10 @@ function MoneyRequestReportTransactionList({ const accountID = currentUserDetails.accountID ?? CONST.DEFAULT_NUMBER_ID; for (const transaction of resolvedTransactions) { - map.set(transaction.transactionID, filterTransactionViolations(transaction, allTransactionViolations, email, accountID, report, policy ?? undefined)); + map.set(transaction.transactionID, filterTransactionViolations(transaction, allTransactionViolations, email, accountID, report, ownerLogin, policy ?? undefined)); } return map; - }, [resolvedTransactions, allTransactionViolations, currentUserDetails.email, currentUserDetails.accountID, report, policy]); + }, [resolvedTransactions, allTransactionViolations, currentUserDetails.email, currentUserDetails.accountID, report, ownerLogin, policy]); const renderTransactionItem = (transaction: TransactionWithOptionalHighlight) => ( ({ return reportItem?.transactions?.some((transaction) => { const relevantViolations = (transaction.violations ?? []).filter( (violation) => - !isViolationDismissed(transaction, violation, currentUserDetails.email ?? '', currentUserDetails.accountID, reportForViolations, policyForViolations) && + !isViolationDismissed(transaction, violation, currentUserDetails.email ?? '', currentUserDetails.accountID, reportForViolations, policyForViolations, submitterLogin) && shouldShowViolation(reportForViolations, policyForViolations, violation.name, currentUserDetails.email ?? '', false, transaction), ); @@ -205,7 +205,7 @@ function ExpenseReportListItemInner({ ); return violations.some((violation) => violation.name === CONST.VIOLATIONS.MISSING_ATTENDEES); }); - }, [reportItem, policyCategories, policyForViolations, reportForViolations, currentUserDetails]); + }, [reportItem, policyCategories, policyForViolations, reportForViolations, currentUserDetails, submitterLogin]); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); diff --git a/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx b/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx index 0a44cb209e81..24cd10bc0082 100644 --- a/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx +++ b/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx @@ -169,7 +169,7 @@ function TransactionListItemInner({ const onyxViolations = (transactionViolationsForRow ?? []).filter( (violation: TransactionViolation) => - !isViolationDismissed(transactionItem, violation, currentUserDetails.email ?? '', currentUserDetails.accountID, reportForViolations, policyForViolations) && + !isViolationDismissed(transactionItem, violation, currentUserDetails.email ?? '', currentUserDetails.accountID, reportForViolations, policyForViolations, submitterLogin) && shouldShowViolation(reportForViolations, policyForViolations, violation.name, currentUserDetails.email ?? '', false, transactionItem), ); diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index fd160b951b22..53bf2d46b59c 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -59,6 +59,7 @@ import type {TupleToUnion} from 'type-fest'; import {delegateEmailSelector, isUserValidatedSelector} from '@selectors/Account'; import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import truncate from 'lodash/truncate'; import React, {useCallback, useContext} from 'react'; import {View} from 'react-native'; @@ -125,6 +126,7 @@ function SettlementButton({ const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID || CONST.DEFAULT_NUMBER_ID}`); const [conciergeReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [iouReportNextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(iouReport?.ownerAccountID)}); const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: isUserValidatedSelector}); const [amountOwed] = useOnyx(ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED); const policyEmployeeAccountIDs = getPolicyEmployeeAccountIDs(policy, accountID); @@ -524,6 +526,7 @@ function SettlementButton({ userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin, full: false, delegateEmail, }); diff --git a/src/hooks/useHoldMenuSubmit.ts b/src/hooks/useHoldMenuSubmit.ts index 55bd3f0bba88..206bde7d0b5c 100644 --- a/src/hooks/useHoldMenuSubmit.ts +++ b/src/hooks/useHoldMenuSubmit.ts @@ -15,6 +15,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {delegateEmailSelector} from '@selectors/Account'; import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; import useOnyx from './useOnyx'; @@ -48,6 +49,7 @@ function useHoldMenuSubmit({moneyRequestReport, chatReport, requestType, payment const [delegateEmail] = useOnyx(ONYXKEYS.ACCOUNT, {selector: delegateEmailSelector}); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); const [moneyRequestReportNextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${moneyRequestReport?.reportID}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(moneyRequestReport?.ownerAccountID)}); const {isBetaEnabled} = usePermissions(); const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); @@ -86,6 +88,7 @@ function useHoldMenuSubmit({moneyRequestReport, chatReport, requestType, payment userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin, full, onApproved: animationCallback, expenseReportPolicy: policy, diff --git a/src/hooks/useLifecycleActions.tsx b/src/hooks/useLifecycleActions.tsx index b65e83654565..3c1fa2433dea 100644 --- a/src/hooks/useLifecycleActions.tsx +++ b/src/hooks/useLifecycleActions.tsx @@ -192,6 +192,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin: submitterLogin, full: true, onApproved: () => { if (skipAnimation) { diff --git a/src/hooks/useMoneyReportHeaderStatusBar.ts b/src/hooks/useMoneyReportHeaderStatusBar.ts index 30f039ac699e..c5285129c72f 100644 --- a/src/hooks/useMoneyReportHeaderStatusBar.ts +++ b/src/hooks/useMoneyReportHeaderStatusBar.ts @@ -20,6 +20,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {ValueOf} from 'type-fest'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import {getArchiveReason} from '@selectors/Report'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; @@ -43,6 +44,7 @@ function useMoneyReportHeaderStatusBar(reportID: string | undefined, chatReportI const {accountID, email} = useCurrentUserPersonalDetails(); const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(moneyRequestReport?.ownerAccountID)}); const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(moneyRequestReport?.policyID)}`); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); @@ -81,7 +83,7 @@ function useMoneyReportHeaderStatusBar(reportID: string | undefined, chatReportI const hasOnlyHeldExpenses = hasOnlyHeldExpensesReportUtils(transactions); const isPayAtEndExpense = isPayAtEndExpenseTransactionUtils(transaction); const isReportSettled = isSettledReportUtils(moneyRequestReport); - const hasDuplicates = !isReportSettled && hasDuplicateTransactions(email ?? '', accountID, moneyRequestReport, policy, allTransactionViolations); + const hasDuplicates = !isReportSettled && hasDuplicateTransactions(email ?? '', accountID, moneyRequestReport, ownerLogin, policy, allTransactionViolations); const shouldShowMarkAsResolved = isMarkAsResolvedAction(moneyRequestReport, transactionViolations); const shouldShowStatusBar = diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index 30a35e7bf474..f6f568ab07f1 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -848,6 +848,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin: getLoginByAccountID(expenseReport.ownerAccountID, personalDetails), delegateEmail, full: true, additionalOnyxData: getSearchApproveOnyxData(hash, reportID, currentSearchKey), @@ -889,6 +890,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { betas, delegateEmail, currentSearchKey, + personalDetails, ]); const {expenseCount, uniqueReportCount} = useMemo(() => { diff --git a/src/hooks/useSelectionModePayment.ts b/src/hooks/useSelectionModePayment.ts index e06c83502dfe..88f0fefa5f84 100644 --- a/src/hooks/useSelectionModePayment.ts +++ b/src/hooks/useSelectionModePayment.ts @@ -27,6 +27,7 @@ import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import {delegateEmailSelector, isUserValidatedSelector} from '@selectors/Account'; import {hasSeenTourSelector} from '@selectors/Onboarding'; +import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import truncate from 'lodash/truncate'; import {useContext, useEffect, useRef} from 'react'; @@ -89,6 +90,7 @@ function useSelectionModePayment({ const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, currentSearchQueryJSON?.hash, true); const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(reportID)}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(moneyRequestReport?.ownerAccountID)}); const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(moneyRequestReport?.chatReportID)}`); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(moneyRequestReport?.policyID)}`); const [session] = useOnyx(ONYXKEYS.SESSION); @@ -303,6 +305,7 @@ function useSelectionModePayment({ ownerBillingGracePeriodEnd, delegateEmail, expenseReportPolicy: policy, + ownerLogin, }); }; diff --git a/src/hooks/useTransactionViolations.ts b/src/hooks/useTransactionViolations.ts index f249be217b95..4397023f2bb8 100644 --- a/src/hooks/useTransactionViolations.ts +++ b/src/hooks/useTransactionViolations.ts @@ -4,6 +4,7 @@ import {getVisibleTransactionViolations, isDistanceRequest} from '@libs/Transact import {syncCustomUnitRateOutOfDateRangeViolation} from '@libs/Violations/ViolationsUtils'; import ONYXKEYS from '@src/ONYXKEYS'; +import {personalDetailsLoginSelector} from '@src/selectors/PersonalDetails'; import type {Policy, TransactionViolation, TransactionViolations} from '@src/types/onyx'; import getEmptyArray from '@src/types/utils/getEmptyArray'; @@ -19,6 +20,7 @@ function useTransactionViolations(transactionID?: string, shouldShowRterForSettl const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); const [transactionViolations = getEmptyArray()] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`); const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(transaction?.reportID)}`); + const [ownerLogin] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsLoginSelector(iouReport?.ownerAccountID)}); const [reportPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`); const customUnitRateID = isDistanceRequest(transaction) ? transaction?.comment?.customUnit?.customUnitRateID : undefined; const shouldLookupDistancePolicy = !policyOverride && !!customUnitRateID && !getDistanceRateCustomUnitRate(reportPolicy, customUnitRateID); @@ -35,10 +37,11 @@ function useTransactionViolations(transactionID?: string, shouldShowRterForSettl currentUserDetails.email ?? '', currentUserDetails.accountID, iouReport, + ownerLogin, policy, shouldShowRterForSettledReport, ); - }, [transaction, transactionViolations, iouReport, policy, shouldShowRterForSettledReport, currentUserDetails.email, currentUserDetails.accountID]); + }, [transaction, transactionViolations, iouReport, ownerLogin, policy, shouldShowRterForSettledReport, currentUserDetails.email, currentUserDetails.accountID]); } export default useTransactionViolations; diff --git a/src/libs/PaymentUtils.ts b/src/libs/PaymentUtils.ts index 0b7c1374cd82..68a47ee8a840 100644 --- a/src/libs/PaymentUtils.ts +++ b/src/libs/PaymentUtils.ts @@ -55,6 +55,7 @@ type SelectPaymentTypeParams = { amountOwed: OnyxEntry; ownerBillingGracePeriodEnd: OnyxEntry; delegateEmail: string | undefined; + ownerLogin: string | undefined; }; type BusinessBankAccountOption = { @@ -252,6 +253,7 @@ const selectPaymentType = (params: SelectPaymentTypeParams) => { amountOwed, ownerBillingGracePeriodEnd, delegateEmail, + ownerLogin, } = params; if (policy && shouldRestrictUserBillableActions(policy, ownerBillingGracePeriodEnd, userBillingGracePeriodEnds, amountOwed, currentAccountID)) { Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(policy.id)); @@ -287,6 +289,7 @@ const selectPaymentType = (params: SelectPaymentTypeParams) => { userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin, full: true, delegateEmail, }); diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index 05882c22f745..f7cecce43dc8 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -338,6 +338,7 @@ function isRemoveHoldAction(report: Report, chatReport: OnyxEntry, repor function isReviewDuplicatesAction( report: Report, + ownerLogin: string | undefined, reportTransactions: Transaction[], currentUserEmail: string, currentUserAccountID: number, @@ -345,7 +346,7 @@ function isReviewDuplicatesAction( violations: OnyxCollection, ) { const hasDuplicates = reportTransactions.some((transaction) => - isDuplicate(transaction, currentUserEmail, currentUserAccountID, report, policy, violations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID]), + isDuplicate(transaction, currentUserEmail, currentUserAccountID, report, ownerLogin, policy, violations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID]), ); if (!hasDuplicates) { @@ -503,7 +504,7 @@ function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf, @@ -598,7 +600,7 @@ function getTransactionThreadPrimaryAction( [`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${reportTransaction.transactionID}`]: violations, }; - if (isReviewDuplicatesAction(parentReport, [reportTransaction], currentUserLogin, currentUserAccountID, policy, transactionViolations)) { + if (isReviewDuplicatesAction(parentReport, parentOwnerLogin, [reportTransaction], currentUserLogin, currentUserAccountID, policy, transactionViolations)) { return isFromReviewDuplicates ? CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.KEEP_THIS_ONE : CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REVIEW_DUPLICATES; } diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts index 5b73ff9357e4..a3e4f747a6c3 100644 --- a/src/libs/ReportSecondaryActionUtils.ts +++ b/src/libs/ReportSecondaryActionUtils.ts @@ -293,6 +293,7 @@ function isApproveAction( currentUserLogin: string, currentUserAccountID: number, report: Report, + ownerLogin: string | undefined, reportTransactions: Transaction[], violations: OnyxCollection, reportMetadata: OnyxEntry, @@ -331,7 +332,7 @@ function isApproveAction( } const isExpenseReport = isExpenseReportUtils(report); const reportHasDuplicatedTransactions = reportTransactions.some((transaction) => - isDuplicate(transaction, currentUserLogin, currentUserAccountID, report, policy, violations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID]), + isDuplicate(transaction, currentUserLogin, currentUserAccountID, report, ownerLogin, policy, violations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID]), ); if (isExpenseReport && isProcessingReport && reportHasDuplicatedTransactions) { @@ -1004,7 +1005,7 @@ function getSecondaryReportActions({ options.push(CONST.REPORT.SECONDARY_ACTIONS.SUBMIT); } - if (isApproveAction(currentUserLogin, currentUserAccountID, report, reportTransactions, violations, reportMetadata, policy)) { + if (isApproveAction(currentUserLogin, currentUserAccountID, report, submitterLogin, reportTransactions, violations, reportMetadata, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.APPROVE); } diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 89cd20e19bcb..c5dd7c74ea73 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -1780,13 +1780,14 @@ function getVisibleTransactionViolations( currentUserEmail: string, currentUserAccountID: number, iouReport: OnyxEntry, + iouReportOwnerLogin: string | undefined, policy: OnyxEntry, shouldShowRterForSettledReport = true, ): TransactionViolations { return mergeProhibitedViolations( transactionViolations.filter( (violation) => - !isViolationDismissed(transaction, violation, currentUserEmail, currentUserAccountID, iouReport, policy) && + !isViolationDismissed(transaction, violation, currentUserEmail, currentUserAccountID, iouReport, policy, iouReportOwnerLogin) && shouldShowViolation(iouReport, policy, violation.name, currentUserEmail, shouldShowRterForSettledReport, transaction), ), ); @@ -1985,6 +1986,7 @@ function isDuplicate( currentUserEmail: string, currentUserAccountID: number, iouReport: OnyxEntry, + iouReportOwnerLogin: string | undefined, policy: OnyxEntry, transactionViolation: OnyxEntry, ): boolean { @@ -1994,7 +1996,15 @@ function isDuplicate( const duplicatedTransactionViolation = transactionViolation?.find((violation: TransactionViolation) => violation.name === CONST.VIOLATIONS.DUPLICATED_TRANSACTION); const hasDuplicatedTransactionViolation = !!duplicatedTransactionViolation; - const isDuplicatedTransactionViolationDismissed = isViolationDismissed(transaction, duplicatedTransactionViolation, currentUserEmail, currentUserAccountID, iouReport, policy); + const isDuplicatedTransactionViolationDismissed = isViolationDismissed( + transaction, + duplicatedTransactionViolation, + currentUserEmail, + currentUserAccountID, + iouReport, + policy, + iouReportOwnerLogin, + ); return hasDuplicatedTransactionViolation && !isDuplicatedTransactionViolationDismissed; } @@ -2020,6 +2030,7 @@ function isViolationDismissed( currentUserAccountID: number, iouReport: OnyxEntry, policy: OnyxEntry, + iouReportOwnerLogin?: string, ): boolean { if (!transaction || !violation) { return false; @@ -2051,7 +2062,7 @@ function isViolationDismissed( const shouldViewAsSubmitter = !isSubmitter && isOpenExpenseReport(iouReport); if (shouldViewAsSubmitter && iouReport.ownerAccountID) { - const reportOwnerEmail = getLoginsByAccountIDs([iouReport.ownerAccountID]).at(0); + const reportOwnerEmail = iouReportOwnerLogin ?? getLoginsByAccountIDs([iouReport.ownerAccountID]).at(0); if (reportOwnerEmail && dismissedByEmails.includes(reportOwnerEmail)) { return true; } @@ -2099,6 +2110,7 @@ function hasDuplicateTransactions( currentUserEmail: string, currentUserAccountID: number, iouReport: OnyxEntry, + ownerLogin: string | undefined, policy: OnyxEntry, allTransactionViolations: OnyxCollection, ): boolean { @@ -2113,6 +2125,7 @@ function hasDuplicateTransactions( currentUserEmail, currentUserAccountID, iouReport, + ownerLogin, policy, allTransactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID], ), diff --git a/src/libs/actions/IOU/ReportWorkflow.ts b/src/libs/actions/IOU/ReportWorkflow.ts index 8506df981322..4a55317025cf 100644 --- a/src/libs/actions/IOU/ReportWorkflow.ts +++ b/src/libs/actions/IOU/ReportWorkflow.ts @@ -66,7 +66,6 @@ import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import { allHavePendingRTERViolation, hasAnyTransactionWithoutRTERViolation, - hasDuplicateTransactions, hasSmartScanFailedWithMissingFields, hasSubmissionBlockingViolations, isDuplicate, @@ -111,6 +110,7 @@ type ApproveMoneyRequestFunctionParams = { onApproved?: () => void; ownerBillingGracePeriodEnd: OnyxEntry; delegateEmail: string | undefined; + ownerLogin: string | undefined; additionalOnyxData?: AdditionalPayOnyxData; shouldPlaySuccessSound?: boolean; }; @@ -440,6 +440,7 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { onApproved, ownerBillingGracePeriodEnd, delegateEmail, + ownerLogin, expenseReportPolicy, additionalOnyxData, shouldPlaySuccessSound = true, @@ -466,9 +467,6 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { const unheldTotal = getUnheldReimbursableTotal(expenseReport) + (expenseReport.unheldNonReimbursableTotal ?? 0); let total = getReimbursableTotal(expenseReport) + (expenseReport.nonReimbursableTotal ?? 0); const hasHeldExpenses = hasHeldExpensesReportUtils(reportTransactions); - // TODO: https://github.com/Expensify/App/issues/66512 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const hasDuplicates = hasDuplicateTransactions(currentUserEmailParam, currentUserAccountIDParam, expenseReport, expenseReportPolicy, getAllTransactionViolations()); if (hasHeldExpenses && !full && !!unheldTotal) { total = unheldTotal; } @@ -759,24 +757,22 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { } // Remove duplicates violations if we approve the report - if (hasDuplicates) { - let transactions = getReportTransactions(expenseReport.reportID).filter((transaction) => - isDuplicate( - transaction, - currentUserEmailParam, - currentUserAccountIDParam, - expenseReport, - expenseReportPolicy, - // TODO: https://github.com/Expensify/App/issues/66512 - // eslint-disable-next-line @typescript-eslint/no-deprecated - getAllTransactionViolations()?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID], - ), - ); - if (!full) { - transactions = transactions.filter((transaction) => !isOnHold(transaction)); - } - - for (const transaction of transactions) { + const duplicatedTransactions = getReportTransactions(expenseReport.reportID).filter((transaction) => + isDuplicate( + transaction, + currentUserEmailParam, + currentUserAccountIDParam, + expenseReport, + ownerLogin, + expenseReportPolicy, + // TODO: https://github.com/Expensify/App/issues/66512 + // eslint-disable-next-line @typescript-eslint/no-deprecated + getAllTransactionViolations()?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transaction.transactionID], + ), + ); + if (duplicatedTransactions.length) { + const filteredTransactions = !full ? duplicatedTransactions.filter((transaction) => !isOnHold(transaction)) : duplicatedTransactions; + for (const transaction of filteredTransactions) { // TODO: https://github.com/Expensify/App/issues/66512 // eslint-disable-next-line @typescript-eslint/no-deprecated const transactionViolations = getAllTransactionViolations()?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`] ?? []; diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index dfaee0078f28..2f77ab59909a 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -2220,7 +2220,7 @@ function createTransactionThreadReport(params: CreateTransactionThreadReportPara if (iouReportAction?.actorAccountID && iouReportAction.actorAccountID !== currentUserAccountID) { participantAccountIDsForDetails.push(iouReportAction.actorAccountID); } - const participantLogins = PersonalDetailsUtils.getLoginsByAccountIDs(participantAccountIDsForDetails); + const participantLogins = PersonalDetailsUtils.getLoginsByAccountIDs(participantAccountIDsForDetails, personalDetails ?? allPersonalDetails); const participants = buildParticipantInfoFromLogins(participantLogins); openReport({ reportID: optimisticTransactionThreadReportID, @@ -2551,8 +2551,7 @@ function createChildReport( }; } - const participantAccountIDsForDetails = Object.keys(newChat.participants ?? {}).map(Number); - const participantLogins = PersonalDetailsUtils.getLoginsByAccountIDs(participantAccountIDsForDetails); + const participantLogins = PersonalDetailsUtils.getLoginsByAccountIDs(participantAccountIDs, participantsPersonalDetails); const participants = buildParticipantInfoFromLogins(participantLogins); openReport({ diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 2f29d73f1177..115e786209ac 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -341,6 +341,7 @@ function handleActionButtonPress({ amountOwed, iouReportCurrentNextStepDeprecated, delegateEmail, + ownerLogin: submitterLogin, }); return; case CONST.SEARCH.ACTION_TYPES.SUBMIT: { @@ -605,6 +606,7 @@ type GetApproveActionCallbackParams = { amountOwed: OnyxEntry; iouReportCurrentNextStepDeprecated?: OnyxEntry; delegateEmail?: string; + ownerLogin: string | undefined; }; function getApproveActionCallback({ @@ -622,6 +624,7 @@ function getApproveActionCallback({ amountOwed, iouReportCurrentNextStepDeprecated, delegateEmail, + ownerLogin, }: GetApproveActionCallbackParams) { if (!item.reportID) { return; @@ -644,6 +647,7 @@ function getApproveActionCallback({ userBillingGracePeriodEnds, amountOwed, ownerBillingGracePeriodEnd, + ownerLogin, delegateEmail, full: true, additionalOnyxData: getSearchApproveOnyxData(hash, item.reportID, currentSearchKey), diff --git a/src/pages/home/ForYouSection/useReviewFlaggedExpenses.ts b/src/pages/home/ForYouSection/useReviewFlaggedExpenses.ts index f4f8ec945ae4..a21d36838170 100644 --- a/src/pages/home/ForYouSection/useReviewFlaggedExpenses.ts +++ b/src/pages/home/ForYouSection/useReviewFlaggedExpenses.ts @@ -114,7 +114,9 @@ function getFlaggedExpenses( } const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]; - const visibleViolations = getVisibleTransactionViolations(transaction, violations, currentUserEmail, currentUserAccountID, report, policy); + // The report is one of the current user's OPEN expense reports (see isCurrentUserOpenExpenseReport), + // so the report owner is the current user and the owner login is currentUserEmail. + const visibleViolations = getVisibleTransactionViolations(transaction, violations, currentUserEmail, currentUserAccountID, report, currentUserEmail, policy); if (!hasReviewableViolation(visibleViolations)) { continue; } diff --git a/tests/actions/IOUTest/ReportWorkflowTest.ts b/tests/actions/IOUTest/ReportWorkflowTest.ts index 6a2d484ecd63..2bc58b90e0df 100644 --- a/tests/actions/IOUTest/ReportWorkflowTest.ts +++ b/tests/actions/IOUTest/ReportWorkflowTest.ts @@ -2263,6 +2263,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: DELEGATE_EMAIL, + ownerLogin: undefined, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure @@ -2303,6 +2304,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure @@ -2877,6 +2879,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); beforeEach(() => { @@ -3063,6 +3066,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3114,6 +3118,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3161,6 +3166,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3284,6 +3290,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3314,6 +3321,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3342,6 +3350,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3400,6 +3409,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); @@ -3449,6 +3459,7 @@ describe('actions/IOU/ReportWorkflow', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); return waitForBatchedUpdates(); }) @@ -3579,6 +3590,7 @@ describe('actions/IOU/ReportWorkflow', () => { full: false, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }); await waitForBatchedUpdates(); diff --git a/tests/unit/PaymentUtilsTest.ts b/tests/unit/PaymentUtilsTest.ts index 43a4fd50a1d5..6b8f00afce17 100644 --- a/tests/unit/PaymentUtilsTest.ts +++ b/tests/unit/PaymentUtilsTest.ts @@ -199,6 +199,7 @@ describe('PaymentUtils', () => { amountOwed: 0, ownerBillingGracePeriodEnd: undefined, delegateEmail: undefined, + ownerLogin: undefined, }; beforeEach(() => { diff --git a/tests/unit/ReportPrimaryActionUtilsTest.ts b/tests/unit/ReportPrimaryActionUtilsTest.ts index 908f9677cd11..4656abbcb291 100644 --- a/tests/unit/ReportPrimaryActionUtilsTest.ts +++ b/tests/unit/ReportPrimaryActionUtilsTest.ts @@ -1445,7 +1445,7 @@ describe('isReviewDuplicatesAction', () => { ], }; - expect(isReviewDuplicatesAction(report, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, violation)).toBe(true); + expect(isReviewDuplicatesAction(report, undefined, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, violation)).toBe(true); }); it('should return false when report approver has no duplicated transactions', async () => { @@ -1465,7 +1465,7 @@ describe('isReviewDuplicatesAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${TRANSACTION_ID}`, transaction); - expect(isReviewDuplicatesAction(report, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, undefined)).toBe(false); + expect(isReviewDuplicatesAction(report, undefined, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, undefined)).toBe(false); }); it('should return false when current user is neither the report submitter nor approver', async () => { @@ -1486,7 +1486,7 @@ describe('isReviewDuplicatesAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${TRANSACTION_ID}`, transaction); expect( - isReviewDuplicatesAction(report, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, { + isReviewDuplicatesAction(report, undefined, [transaction], CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, undefined, { [`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${TRANSACTION_ID}`]: [ createMock({ name: CONST.VIOLATIONS.DUPLICATED_TRANSACTION, @@ -1536,7 +1536,7 @@ describe('getTransactionThreadPrimaryAction', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${CHILD_REPORT_ID}`, {[HOLD_ACTION_ID]: holdAction}); - expect(getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, report, createMock({}), transaction, [], policy as Policy, false)).toBe( + expect(getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, report, createMock({}), undefined, transaction, [], policy as Policy, false)).toBe( CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REMOVE_HOLD, ); }); @@ -1564,9 +1564,9 @@ describe('getTransactionThreadPrimaryAction', () => { name: CONST.VIOLATIONS.DUPLICATED_TRANSACTION, }); - expect(getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, transaction, [violation], policy as Policy, false)).toBe( - CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REVIEW_DUPLICATES, - ); + expect( + getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, undefined, transaction, [violation], policy as Policy, false), + ).toBe(CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REVIEW_DUPLICATES); }); it('should return MARK AS CASH if has all RTER violations', async () => { @@ -1593,9 +1593,9 @@ describe('getTransactionThreadPrimaryAction', () => { }, }); - expect(getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, transaction, [violation], policy as Policy, false)).toBe( - CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.MARK_AS_CASH, - ); + expect( + getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, undefined, transaction, [violation], policy as Policy, false), + ).toBe(CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.MARK_AS_CASH); }); it('should return MARK AS CASH for broken connection', async () => { @@ -1621,9 +1621,9 @@ describe('getTransactionThreadPrimaryAction', () => { }, }); - expect(getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, transaction, [violation], policy as Policy, false)).toBe( - CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.MARK_AS_CASH, - ); + expect( + getTransactionThreadPrimaryAction(CURRENT_USER_EMAIL, CURRENT_USER_ACCOUNT_ID, createMock({}), report, undefined, transaction, [violation], policy as Policy, false), + ).toBe(CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.MARK_AS_CASH); }); it('Should return empty string when we are waiting for user to add a bank account', async () => { diff --git a/tests/unit/useTransactionViolationsTest.ts b/tests/unit/useTransactionViolationsTest.ts index a38eb9f3c5b8..c7fed6249a59 100644 --- a/tests/unit/useTransactionViolationsTest.ts +++ b/tests/unit/useTransactionViolationsTest.ts @@ -63,13 +63,14 @@ jest.mock('@libs/TransactionUtils', () => { currentUserEmail: string, currentUserAccountID: number, iouReport: Report | undefined, + iouReportOwnerLogin: string | undefined, policy: Policy | undefined, shouldShowRterForSettledReport = true, ) => mergeProhibitedViolations( transactionViolations.filter( (violation) => - !mockIsViolationDismissed(transaction, violation, currentUserEmail, currentUserAccountID, iouReport, policy) && + !mockIsViolationDismissed(transaction, violation, currentUserEmail, currentUserAccountID, iouReport, policy, iouReportOwnerLogin) && mockShouldShowViolation(iouReport, policy, violation.name, currentUserEmail, shouldShowRterForSettledReport, transaction), ), );