Skip to content

Commit

Permalink
Merge pull request #57242 from callstack-internal/VickyStash/bugfix/5…
Browse files Browse the repository at this point in the history
…7162-broken-connection-violations

Follow ups to Broken Connection with direct feeds
  • Loading branch information
mountiny authored Feb 27, 2025
2 parents 4aace3e + 7e6f6b5 commit 971b380
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/components/BrokenConnectionDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type {OnyxEntry} from 'react-native-onyx';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useTransactionViolations from '@hooks/useTransactionViolations';
import {isInstantSubmitEnabled, isPolicyAdmin as isPolicyAdminPolicyUtils} from '@libs/PolicyUtils';
import {isCurrentUserSubmitter, isProcessingReport, isReportApproved, isReportManuallyReimbursed} from '@libs/ReportUtils';
import {isPolicyAdmin as isPolicyAdminPolicyUtils} from '@libs/PolicyUtils';
import {isCurrentUserSubmitter, isReportApproved, isReportManuallyReimbursed} from '@libs/ReportUtils';
import Navigation from '@navigation/Navigation';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
Expand Down Expand Up @@ -52,7 +52,7 @@ function BrokenConnectionDescription({transactionID, policy, report}: BrokenConn
);
}

if (isReportApproved({report}) || isReportManuallyReimbursed(report) || (isProcessingReport(report) && !isInstantSubmitEnabled(policy))) {
if (isReportApproved({report}) || isReportManuallyReimbursed(report)) {
return translate('violations.memberBrokenConnectionError');
}

Expand Down
20 changes: 10 additions & 10 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {convertToDisplayString} from '@libs/CurrencyUtils';
import Navigation from '@libs/Navigation/Navigation';
import {getConnectedIntegration, isPolicyAdmin} from '@libs/PolicyUtils';
import {getConnectedIntegration} from '@libs/PolicyUtils';
import {getOriginalMessage, isDeletedAction, isMoneyRequestAction, isTrackExpenseAction} from '@libs/ReportActionsUtils';
import {
canBeExported,
Expand All @@ -27,13 +27,13 @@ import {
isAllowedToSubmitDraftExpenseReport,
isArchivedReportWithID,
isClosedExpenseReportWithNoExpenses,
isCurrentUserSubmitter,
isInvoiceReport,
navigateBackOnDeleteTransaction,
reportTransactionsSelector,
} from '@libs/ReportUtils';
import {
allHavePendingRTERViolation,
checkIfShouldShowMarkAsCashButton,
isDuplicate as isDuplicateTransactionUtils,
isExpensifyCardTransaction,
isOnHold as isOnHoldTransactionUtils,
Expand Down Expand Up @@ -150,11 +150,12 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const hasOnlyPendingTransactions = useMemo(() => {
return !!transactions && transactions.length > 0 && transactions.every((t) => isExpensifyCardTransaction(t) && isPending(t));
}, [transactions]);
const transactionIDs = transactions?.map((t) => t.transactionID) ?? [];
const [violations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {
selector: (allTransactions) =>
Object.fromEntries(Object.entries(allTransactions ?? {}).filter(([key]) => transactionIDs.includes(key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '')))),
});
const transactionIDs = useMemo(() => transactions?.map((t) => t.transactionID) ?? [], [transactions]);
const [allViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS);
const violations = useMemo(
() => Object.fromEntries(Object.entries(allViolations ?? {}).filter(([key]) => transactionIDs.includes(key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '')))),
[allViolations, transactionIDs],
);
// Check if there is pending rter violation in all transactionViolations with given transactionIDs.
const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDs, violations);
// Check if user should see broken connection violation warning.
Expand All @@ -173,8 +174,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const onlyShowPayElsewhere = useMemo(() => !canIOUBePaid && getCanIOUBePaid(true), [canIOUBePaid, getCanIOUBePaid]);

const shouldShowMarkAsCashButton =
!!transactionThreadReportID &&
(hasAllPendingRTERViolations || (shouldShowBrokenConnectionViolation && (!isPolicyAdmin(policy) || isCurrentUserSubmitter(moneyRequestReport?.reportID))));
!!transactionThreadReportID && checkIfShouldShowMarkAsCashButton(hasAllPendingRTERViolations, shouldShowBrokenConnectionViolation, moneyRequestReport, policy);

const shouldShowPayButton = canIOUBePaid || onlyShowPayElsewhere;

Expand Down Expand Up @@ -300,7 +300,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
if (hasOnlyHeldExpenses) {
return {icon: getStatusIcon(Expensicons.Stopwatch), description: translate('iou.expensesOnHold')};
}
if (shouldShowBrokenConnectionViolation) {
if (!!transaction?.transactionID && shouldShowBrokenConnectionViolation) {
return {
icon: getStatusIcon(Expensicons.Hourglass),
description: (
Expand Down
9 changes: 4 additions & 5 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useTransactionViolations from '@hooks/useTransactionViolations';
import Navigation from '@libs/Navigation/Navigation';
import {isPolicyAdmin} from '@libs/PolicyUtils';
import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {isCurrentUserSubmitter} from '@libs/ReportUtils';
import {
checkIfShouldShowMarkAsCashButton,
hasPendingRTERViolation as hasPendingRTERViolationTransactionUtils,
hasReceipt,
isDuplicate as isDuplicateTransactionUtils,
Expand Down Expand Up @@ -83,8 +82,8 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre

const hasPendingRTERViolation = hasPendingRTERViolationTransactionUtils(transactionViolations);

const shouldShowBrokenConnectionViolation = shouldShowBrokenConnectionViolationTransactionUtils(transaction, report, policy, transactionViolations);
const shouldShowMarkAsCashButton = hasPendingRTERViolation || (shouldShowBrokenConnectionViolation && (!isPolicyAdmin(policy) || isCurrentUserSubmitter(parentReport?.reportID)));
const shouldShowBrokenConnectionViolation = shouldShowBrokenConnectionViolationTransactionUtils(transaction, parentReport, policy, transactionViolations);
const shouldShowMarkAsCashButton = checkIfShouldShowMarkAsCashButton(hasPendingRTERViolation, shouldShowBrokenConnectionViolation, parentReport, policy);

const markAsCash = useCallback(() => {
markAsCashAction(transaction?.transactionID, reportID);
Expand Down Expand Up @@ -115,7 +114,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
description: (
<BrokenConnectionDescription
transactionID={transaction?.transactionID}
report={report}
report={parentReport}
policy={policy}
/>
),
Expand Down
34 changes: 31 additions & 3 deletions src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ import {
isPolicyAdmin,
} from '@libs/PolicyUtils';
import {getOriginalMessage, getReportAction, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {getReportTransactions, isOpenExpenseReport, isProcessingReport, isReportIDApproved, isSettled, isThread} from '@libs/ReportUtils';
import {
getReportTransactions,
isCurrentUserSubmitter,
isOpenExpenseReport,
isProcessingReport,
isReportApproved,
isReportIDApproved,
isReportManuallyReimbursed,
isSettled,
isThread,
} from '@libs/ReportUtils';
import type {IOURequestType} from '@userActions/IOU';
import CONST from '@src/CONST';
import type {IOUType} from '@src/CONST';
Expand Down Expand Up @@ -820,7 +830,7 @@ function shouldShowBrokenConnectionViolation(
// This should not be possible except in the case of incorrect type assertions. Generally TS should prevent this at compile time.
throw new Error('Invalid argument combination. If a transactionIDList is passed in, then an OnyxCollection of violations is expected');
}
violations = transactionOrIDList.flatMap((id) => transactionViolations?.[id] ?? []);
violations = transactionOrIDList.flatMap((id) => transactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${id}`] ?? []);
} else {
if (!Array.isArray(transactionViolations)) {
// This should not be possible except in the case of incorrect type assertions. Generally TS should prevent this at compile time.
Expand All @@ -830,7 +840,24 @@ function shouldShowBrokenConnectionViolation(
}

const brokenConnectionViolations = violations.filter((violation) => isBrokenConnectionViolation(violation));
return brokenConnectionViolations.length > 0 && (!isPolicyAdmin(policy) || isOpenExpenseReport(report) || (isProcessingReport(report) && isInstantSubmitEnabled(policy)));

if (brokenConnectionViolations.length > 0) {
if (!isPolicyAdmin(policy) || isCurrentUserSubmitter(report?.reportID)) {
return true;
}
return isOpenExpenseReport(report) || (isProcessingReport(report) && isInstantSubmitEnabled(policy));
}

return false;
}

function checkIfShouldShowMarkAsCashButton(hasRTERVPendingViolation: boolean, shouldDisplayBrokenConnectionViolation: boolean, report: OnyxEntry<Report>, policy: OnyxEntry<Policy>) {
if (hasRTERVPendingViolation) {
return true;
}
return (
shouldDisplayBrokenConnectionViolation && (!isPolicyAdmin(policy) || isCurrentUserSubmitter(report?.reportID)) && !isReportApproved({report}) && !isReportManuallyReimbursed(report)
);
}

/**
Expand Down Expand Up @@ -1518,6 +1545,7 @@ export {
isPerDiemRequest,
isViolationDismissed,
isBrokenConnectionViolation,
checkIfShouldShowMarkAsCashButton,
shouldShowRTERViolationMessage,
};

Expand Down

0 comments on commit 971b380

Please sign in to comment.