Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/LHNOptionsList/LHNOptionsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,9 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
const reportID = item.reportID;
const itemParentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${item.parentReportID}`];
const itemReportNameValuePairs = reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`];
const chatReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${item.chatReportID}`];
const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`];
const itemOneTransactionThreadReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${getOneTransactionThreadReportID(reportID, itemReportActions, isOffline)}`];
const itemOneTransactionThreadReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${getOneTransactionThreadReportID(item, chatReport, itemReportActions, isOffline)}`];
const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${item?.parentReportID}`];
const itemParentReportAction = item?.parentReportActionID ? itemParentReportActions?.[item?.parentReportActionID] : undefined;
const itemReportAttributes = reportAttributes?.[reportID];
Expand Down
16 changes: 9 additions & 7 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,15 @@ function MoneyReportHeader({
}
return getReportPrimaryAction({
report: moneyRequestReport,
chatReport,
reportTransactions: transactions,
violations,
policy,
reportNameValuePairs,
reportActions,
isChatReportArchived,
});
}, [isPaidAnimationRunning, moneyRequestReport, reportNameValuePairs, policy, transactions, violations, reportActions, isChatReportArchived]);
}, [isPaidAnimationRunning, moneyRequestReport, reportNameValuePairs, policy, transactions, violations, reportActions, isChatReportArchived, chatReport]);

const confirmExport = useCallback(() => {
setExportModalStatus(null);
Expand Down Expand Up @@ -627,18 +628,19 @@ function MoneyReportHeader({
if (!moneyRequestReport) {
return [];
}
return getSecondaryReportActions(
moneyRequestReport,
transactions,
return getSecondaryReportActions({
report: moneyRequestReport,
chatReport,
reportTransactions: transactions,
violations,
policy,
reportNameValuePairs,
reportActions,
policies,
isBetaEnabled(CONST.BETAS.RETRACT_NEWDOT),
canUseRetractNewDot: isBetaEnabled(CONST.BETAS.RETRACT_NEWDOT),
isChatReportArchived,
);
}, [moneyRequestReport, transactions, violations, policy, reportNameValuePairs, reportActions, policies, isBetaEnabled, isChatReportArchived]);
});
}, [moneyRequestReport, transactions, violations, policy, reportNameValuePairs, reportActions, policies, isBetaEnabled, chatReport, isChatReportArchived]);

const secondaryActionsImplementation: Record<
ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function MoneyRequestReportActionsList({
const isFocused = useIsFocused();
const route = useRoute<PlatformStackRouteProp<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT>>();
const reportTransactionIDs = transactions.map((transaction) => transaction.transactionID);
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(report?.chatReportID)}`, {canBeMissing: true});

const reportID = report?.reportID;
const linkedReportActionID = route?.params?.reportActionID;
Expand All @@ -137,7 +138,7 @@ function MoneyRequestReportActionsList({

const transactionsWithoutPendingDelete = useMemo(() => transactions.filter((t) => !isTransactionPendingDelete(t)), [transactions]);
const mostRecentIOUReportActionID = useMemo(() => getMostRecentIOURequestActionID(reportActions), [reportActions]);
const transactionThreadReportID = getOneTransactionThreadReportID(reportID, reportActions ?? [], false, reportTransactionIDs);
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions ?? [], false, reportTransactionIDs);
const firstVisibleReportActionID = useMemo(() => getFirstVisibleReportActionID(reportActions, isOffline), [reportActions, isOffline]);
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`, {canBeMissing: true});
const [currentUserAccountID] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: false, selector: (session) => session?.accountID});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP, {canBeMissing: true});
const [isComposerFullSize] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${reportID}`, {initialValue: false, canBeMissing: true});
const {reportPendingAction, reportErrors} = getReportOfflinePendingActionAndErrors(report);
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(report?.chatReportID)}`, {canBeMissing: true});

const {reportActions: unfilteredReportActions, hasNewerActions, hasOlderActions} = usePaginatedReportActions(reportID);
const reportActions = getFilteredReportActionsForReportView(unfilteredReportActions);
Expand All @@ -103,7 +104,7 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
});

const reportTransactionIDs = transactions?.map((transaction) => transaction.transactionID);
const transactionThreadReportID = getOneTransactionThreadReportID(reportID, reportActions ?? [], isOffline, reportTransactionIDs);
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions ?? [], isOffline, reportTransactionIDs);

const prevTransactions = usePrevious(transactions);

Expand Down
2 changes: 1 addition & 1 deletion src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ function ReportPreview({
numberOfRequests === 1 && (!!formattedMerchant || !!formattedDescription) && !(hasOnlyTransactionsWithPendingRoutes && !totalDisplaySpend);
const shouldShowSubtitle = !areAllTransactionsScanning && (shouldShowSingleRequestMerchantOrDescription || numberOfRequests > 1) && !isDisplayAmountZero(getDisplayAmount());

const isPayAtEndExpense = isPayAtEndExpenseReport(iouReportID, transactions);
const isPayAtEndExpense = isPayAtEndExpenseReport(iouReport, transactions);
const [archiveReason] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {selector: getArchiveReason, canBeMissing: false});

const getPendingMessageProps: () => PendingMessageProps = () => {
Expand Down
6 changes: 4 additions & 2 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,7 @@ function validateTransactionViolationJSON(json: string) {
/**
* Gets the reason for showing LHN row
*/
function getReasonForShowingRowInLHN(report: OnyxEntry<Report>, hasRBR = false, isReportArchived = false): TranslationPaths | null {
function getReasonForShowingRowInLHN(report: OnyxEntry<Report>, chatReport: OnyxEntry<Report>, hasRBR = false, isReportArchived = false): TranslationPaths | null {
if (!report) {
return null;
}
Expand All @@ -1334,6 +1334,7 @@ function getReasonForShowingRowInLHN(report: OnyxEntry<Report>, hasRBR = false,

const reason = reasonForReportToBeInOptionList({
report,
chatReport,
// We can't pass report.reportID because it will cause reason to always be isFocused
currentReportId: '-1',
isInFocusMode: !!isInFocusMode,
Expand Down Expand Up @@ -1390,14 +1391,15 @@ type RBRReasonAndReportAction = {
*/
function getReasonAndReportActionForRBRInLHNRow(
report: Report,
chatReport: OnyxEntry<Report>,
reportActions: OnyxEntry<ReportActions>,
transactions: OnyxCollection<Transaction>,
hasViolations: boolean,
reportErrors: Errors,
isArchivedReport = false,
): RBRReasonAndReportAction | null {
const {reason, reportAction} =
SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, reportActions, hasViolations, reportErrors, transactions, transactionViolations, isArchivedReport) ?? {};
SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, chatReport, reportActions, hasViolations, reportErrors, transactions, transactionViolations, isArchivedReport) ?? {};

if (reason) {
return {reason: `debug.reasonRBR.${reason}`, reportAction};
Expand Down
10 changes: 7 additions & 3 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,12 @@ Onyx.connect({
const reportActionsArray = Object.values(reportActions[1] ?? {});
let sortedReportActions = getSortedReportActions(reportActionsArray, true);
allSortedReportActions[reportID] = sortedReportActions;
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.chatReportID}`];

// If the report is a one-transaction report and has , we need to return the combined reportActions so that the LHN can display modifications
// to the transaction thread or the report itself
const transactionThreadReportID = getOneTransactionThreadReportID(reportID, actions[reportActions[0]]);
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, actions[reportActions[0]]);
if (transactionThreadReportID) {
const transactionThreadReportActionsArray = Object.values(actions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID}`] ?? {});
sortedReportActions = getCombinedReportActions(sortedReportActions, transactionThreadReportID, transactionThreadReportActionsArray, reportID);
Expand All @@ -408,7 +410,6 @@ Onyx.connect({
lastReportActions[reportID] = firstReportAction;
}

const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const isWriteActionAllowed = canUserPerformWriteAction(report);

// The report is only visible if it is the last action not deleted that
Expand Down Expand Up @@ -927,7 +928,8 @@ function createOption(accountIDs: number[], personalDetails: OnyxInputOrEntry<Pe
result.pendingAction = report.pendingFields ? (report.pendingFields.addWorkspaceRoom ?? report.pendingFields.createChat) : undefined;
result.ownerAccountID = report.ownerAccountID;
result.reportID = report.reportID;
const oneTransactionThreadReportID = getOneTransactionThreadReportID(report.reportID, allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`]);
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.chatReportID}`];
const oneTransactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`]);
const oneTransactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${oneTransactionThreadReportID}`];
result.isUnread = isUnread(report, oneTransactionThreadReport);
result.isPinned = report.isPinned;
Expand Down Expand Up @@ -1578,10 +1580,12 @@ function getValidReports(reports: OptionList['reports'], config: GetValidReports
// eslint-disable-next-line rulesdir/prefer-at
const option = reports[i];
const report = option.item;
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.chatReportID}`];
const doesReportHaveViolations = shouldDisplayViolationsRBRInLHN(report, transactionViolations);

const shouldBeInOptionList = shouldReportBeInOptionList({
report,
chatReport,
currentReportId: topmostReportId,
betas,
policies,
Expand Down
12 changes: 6 additions & 6 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1180,8 +1180,8 @@ function isTagModificationAction(actionName: string): boolean {
* Used for Send Money flow, which is a special case where we have no IOU create action and only one IOU pay action.
* In other reports, pay actions do not count as a transactions, but this is an exception to this rule.
*/
function getSendMoneyFlowOneTransactionThreadID(actions: OnyxEntry<ReportActions> | ReportAction[], chatReportID?: string) {
if (!chatReportID) {
function getSendMoneyFlowOneTransactionThreadID(actions: OnyxEntry<ReportActions> | ReportAction[], chatReport: OnyxEntry<Report>) {
if (!chatReport) {
return undefined;
}

Expand All @@ -1195,7 +1195,7 @@ function getSendMoneyFlowOneTransactionThreadID(actions: OnyxEntry<ReportActions
// ...which is 'pay'...
const isFirstActionPay = getOriginalMessage(iouActions.at(0))?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY;

const {type, chatType, parentReportID, parentReportActionID} = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? {};
const {type, chatType, parentReportID, parentReportActionID} = chatReport;

// ...and can only be triggered on DM chats
const isDM = type === CONST.REPORT.TYPE.CHAT && !chatType && !(parentReportID && parentReportActionID);
Expand Down Expand Up @@ -1239,13 +1239,13 @@ const isIOUActionMatchingTransactionList = (
* Returns a reportID if there is exactly one transaction thread for the report, and null otherwise.
*/
function getOneTransactionThreadReportID(
reportID: string | undefined,
report: OnyxEntry<Report>,
chatReport: OnyxEntry<Report>,
reportActions: OnyxEntry<ReportActions> | ReportAction[],
isOffline: boolean | undefined = undefined,
reportTransactionIDs?: string[],
): string | undefined {
// If the report is not an IOU, Expense report, or Invoice, it shouldn't be treated as one-transaction report.
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE && report?.type !== CONST.REPORT.TYPE.INVOICE) {
return;
}
Expand All @@ -1255,7 +1255,7 @@ function getOneTransactionThreadReportID(
return;
}

const sendMoneyFlowID = getSendMoneyFlowOneTransactionThreadID(reportActions, report?.chatReportID);
const sendMoneyFlowID = getSendMoneyFlowOneTransactionThreadID(reportActions, chatReport);

if (sendMoneyFlowID) {
return sendMoneyFlowID;
Expand Down
11 changes: 6 additions & 5 deletions src/libs/ReportPrimaryActionUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {OnyxCollection} from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import CONST from '@src/CONST';
import type {Policy, Report, ReportAction, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
Expand Down Expand Up @@ -48,6 +48,7 @@ import {

type GetReportPrimaryActionParams = {
report: Report;
chatReport: OnyxEntry<Report>;
reportTransactions: Transaction[];
violations: OnyxCollection<TransactionViolation[]>;
policy?: Policy;
Expand Down Expand Up @@ -225,15 +226,15 @@ function isExportAction(report: Report, policy?: Policy, reportActions?: ReportA
return false;
}

function isRemoveHoldAction(report: Report, reportTransactions: Transaction[]) {
function isRemoveHoldAction(report: Report, chatReport: OnyxEntry<Report>, reportTransactions: Transaction[]) {
const isReportOnHold = reportTransactions.some(isOnHoldTransactionUtils);

if (!isReportOnHold) {
return false;
}

const reportActions = getAllReportActions(report.reportID);
const transactionThreadReportID = getOneTransactionThreadReportID(report.reportID, reportActions);
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions);

if (!transactionThreadReportID) {
return false;
Expand Down Expand Up @@ -299,7 +300,7 @@ function getAllExpensesToHoldIfApplicable(report?: Report, reportActions?: Repor
}

function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS> | '' {
const {report, reportTransactions, violations, policy, reportNameValuePairs, reportActions, isChatReportArchived} = params;
const {report, reportTransactions, violations, policy, reportNameValuePairs, reportActions, isChatReportArchived, chatReport} = params;

const isPayActionWithAllExpensesHeld = isPrimaryPayAction(report, policy, reportNameValuePairs, isChatReportArchived) && hasOnlyHeldExpenses(report?.reportID);

Expand All @@ -315,7 +316,7 @@ function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf<t
return CONST.REPORT.PRIMARY_ACTIONS.REVIEW_DUPLICATES;
}

if (isRemoveHoldAction(report, reportTransactions) || isPayActionWithAllExpensesHeld) {
if (isRemoveHoldAction(report, chatReport, reportTransactions) || isPayActionWithAllExpensesHeld) {
return CONST.REPORT.PRIMARY_ACTIONS.REMOVE_HOLD;
}

Expand Down
39 changes: 26 additions & 13 deletions src/libs/ReportSecondaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ function isMarkAsExportedAction(report: Report, policy?: Policy): boolean {
return (isAdmin && syncEnabled) || (isExporter && !syncEnabled);
}

function isHoldAction(report: Report, reportTransactions: Transaction[], reportActions?: ReportAction[]): boolean {
const transactionThreadReportID = getOneTransactionThreadReportID(report.reportID, reportActions);
function isHoldAction(report: Report, chatReport: OnyxEntry<Report>, reportTransactions: Transaction[], reportActions?: ReportAction[]): boolean {
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions);
const isOneExpenseReport = reportTransactions.length === 1;
const transaction = reportTransactions.at(0);

Expand Down Expand Up @@ -484,17 +484,30 @@ function isReopenAction(report: Report, policy?: Policy): boolean {
return true;
}

function getSecondaryReportActions(
report: Report,
reportTransactions: Transaction[],
violations: OnyxCollection<TransactionViolation[]>,
policy?: Policy,
reportNameValuePairs?: ReportNameValuePairs,
reportActions?: ReportAction[],
policies?: OnyxCollection<Policy>,
canUseRetractNewDot?: boolean,
function getSecondaryReportActions({
report,
chatReport,
reportTransactions,
violations,
policy,
reportNameValuePairs,
reportActions,
policies,
canUseRetractNewDot,
isChatReportArchived = false,
): Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> {
}: {
report: Report;
chatReport: OnyxEntry<Report>;
reportTransactions: Transaction[];
violations: OnyxCollection<TransactionViolation[]>;
policy?: Policy;
reportNameValuePairs?: ReportNameValuePairs;
reportActions?: ReportAction[];
policies?: OnyxCollection<Policy>;
canUseRetractNewDot?: boolean;
canUseNewDotSplits?: boolean;
isChatReportArchived?: boolean;
}): Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> {
const options: Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> = [];

if (isPrimaryPayAction(report, policy, reportNameValuePairs) && hasOnlyHeldExpenses(report?.reportID)) {
Expand Down Expand Up @@ -537,7 +550,7 @@ function getSecondaryReportActions(
options.push(CONST.REPORT.SECONDARY_ACTIONS.REOPEN);
}

if (isHoldAction(report, reportTransactions, reportActions)) {
if (isHoldAction(report, chatReport, reportTransactions, reportActions)) {
options.push(CONST.REPORT.SECONDARY_ACTIONS.HOLD);
}

Expand Down
Loading