From 2b071461de53d33a659e175706148a91a953ad3f Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Mon, 10 Aug 2026 17:20:22 +0430 Subject: [PATCH 01/19] Thread formatPhoneNumber through report preview helpers --- src/components/AvatarWithDisplayName.tsx | 2 +- src/libs/ReportNameUtils.ts | 2 +- src/libs/ReportUtils.ts | 55 +++++++++++-------- src/libs/actions/IOU/MoneyRequestBuilder.ts | 13 ++++- src/libs/actions/IOU/PerDiem.ts | 13 ++++- src/libs/actions/IOU/SendInvoice.ts | 11 +++- src/libs/actions/IOU/Split.ts | 27 +++++++-- src/pages/DynamicReportDetailsPage.tsx | 2 +- src/pages/ShareCodePage.tsx | 2 +- .../report/ContextMenu/ContextMenuActions.tsx | 2 +- .../AttachmentPickerWithMenuItems.tsx | 4 +- .../ReimbursementDeQueuedContent.tsx | 3 +- .../iou/request/DistanceRequestStartPage.tsx | 6 +- src/pages/iou/request/IOURequestStartPage.tsx | 6 +- 14 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 16a0028d1d1d..67912c6814b8 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -213,7 +213,7 @@ function AvatarWithDisplayName({ const title = getReportName(report, getReportNameFromNames(derivedReportNames, report?.reportID)); const isParentReportArchived = useReportIsArchived(report?.parentReportID); const subtitle = getChatRoomSubtitle(report, policy, conciergeReportID, translate, true, isReportArchived); - const parentNavigationSubtitleData = getParentNavigationSubtitle(report, policy, conciergeReportID, translate, derivedParentReportName, isParentReportArchived); + const parentNavigationSubtitleData = getParentNavigationSubtitle(report, policy, conciergeReportID, translate, formatPhoneNumber, derivedParentReportName, isParentReportArchived); const isMoneyRequestOrReport = isMoneyRequestReport(report) || isMoneyRequest(report) || isTrackExpenseReport(report) || isInvoiceReport(report); const ownerPersonalDetails = getPersonalDetailsForAccountIDs(report?.ownerAccountID ? [report.ownerAccountID] : [], personalDetails); const displayNamesWithTooltips = getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails), false, localeCompare, formatPhoneNumber, translate); diff --git a/src/libs/ReportNameUtils.ts b/src/libs/ReportNameUtils.ts index e88fdd81107a..2b2e070bc9ba 100644 --- a/src/libs/ReportNameUtils.ts +++ b/src/libs/ReportNameUtils.ts @@ -543,7 +543,7 @@ function computeReportNameBasedOnReportAction( if (isReimbursementDeQueuedOrCanceledAction(parentReportAction)) { // Non-React call path: pass the standalone util until this file's own convertToDisplayString threading PR. - return getReimbursementDeQueuedOrCanceledActionMessage(translate, parentReportAction, parentReport?.ownerAccountID, convertToDisplayString); + return getReimbursementDeQueuedOrCanceledActionMessage(translate, formatPhoneNumber, parentReportAction, parentReport?.ownerAccountID, convertToDisplayString); } if (isRejectedAction(parentReportAction)) { return translate('iou.rejectedThisReport'); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a172ba656a26..5c51d29b0406 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -128,7 +128,6 @@ import {getEnvironmentURL} from './Environment/Environment'; import getEnvironment from './Environment/getEnvironment'; import {getMicroSecondOnyxErrorWithTranslationKey, isReceiptError} from './ErrorUtils'; import getAttachmentDetails from './fileDownload/getAttachmentDetails'; -import {formatPhoneNumber as formatPhoneNumberPhoneUtils} from './LocalePhoneNumber'; import {translateLocal} from './Localize'; import Log from './Log'; import {isEmailPublicDomain} from './LoginUtils'; @@ -4236,6 +4235,7 @@ function getReimbursementQueuedActionMessage({ */ function getReimbursementDeQueuedOrCanceledActionMessage( translate: LocalizedTranslate, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], reportAction: OnyxEntry>, reportOwnerAccountID: number | undefined, convertToDisplayString: CurrencyListActionsContextType['convertToDisplayString'], @@ -4247,7 +4247,7 @@ function getReimbursementDeQueuedOrCanceledActionMessage( if (originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN || originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.USER) { return translate('iou.adminCanceledRequest'); } - const submitterDisplayName = getDisplayNameForParticipant({accountID: reportOwnerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + const submitterDisplayName = getDisplayNameForParticipant({accountID: reportOwnerAccountID, shouldUseShortForm: true, formatPhoneNumber, translate}) ?? ''; return translate('iou.canceledRequest', formattedAmount, submitterDisplayName); } @@ -5691,6 +5691,7 @@ type GetReportPreviewMessageBaseParams = { isForListPreview?: boolean; /** This can be either a report preview action or the IOU action. This will be the original report preview action in cases where `iouReportAction` was unwrapped from a report preview action. Otherwise, it will be the same as `iouReportAction`. */ originalReportAction?: OnyxInputOrEntry; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; /** @@ -5722,6 +5723,7 @@ function getReportPreviewMessageForCopy( */ function getReportPreviewMessage( translate: LocalizedTranslate, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], convertToDisplayString: CurrencyListActionsContextType['convertToDisplayString'], params: GetReportPreviewMessageBaseParams, ): string { @@ -5807,7 +5809,7 @@ function getReportPreviewMessage( const policyName = getPolicyName({report: parentReport ?? report, policy, unavailableTranslation: translate('workspace.common.unavailable')}); const payerName = isExpenseReport(report) ? policyName - : getDisplayNameForParticipant({accountID: report.managerID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + : getDisplayNameForParticipant({accountID: report.managerID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber, translate}); const formattedAmount = convertToDisplayString(totalAmount, report.currency); @@ -5864,7 +5866,7 @@ function getReportPreviewMessage( let actualPayerName = report.managerID === deprecatedCurrentUserAccountID && !isForListPreview ? '' - : getDisplayNameForParticipant({accountID: payerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + : getDisplayNameForParticipant({accountID: payerAccountID, shouldUseShortForm: true, formatPhoneNumber, translate}); actualPayerName = actualPayerName && isForListPreview && !isPreviewMessageForParentChatReport ? `${actualPayerName}:` : actualPayerName; const payerDisplayName = isPreviewMessageForParentChatReport ? payerName : actualPayerName; @@ -5888,8 +5890,7 @@ function getReportPreviewMessage( } if (report.isWaitingOnBankAccount) { - const submitterDisplayName = - getDisplayNameForParticipant({accountID: report.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + const submitterDisplayName = getDisplayNameForParticipant({accountID: report.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber, translate}) ?? ''; return translate('iou.waitingOnBankAccount', submitterDisplayName); } @@ -5918,17 +5919,13 @@ function getReportPreviewMessage( // We only want to show the actor name in the preview if it's not the current user who took the action const requestorName = lastActorID && lastActorID !== deprecatedCurrentUserAccountID - ? getDisplayNameForParticipant({accountID: lastActorID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) + ? getDisplayNameForParticipant({accountID: lastActorID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber, translate}) : ''; return `${requestorName ? `${requestorName}: ` : ''}${translate('iou.expenseAmount', amountToDisplay, comment)}`; } if (containsNonReimbursable) { - return translate( - 'iou.payerSpentAmount', - formattedAmount, - getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? '', - ); + return translate('iou.payerSpentAmount', formattedAmount, getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber, translate}) ?? ''); } return translate('iou.payerOwesAmount', formattedAmount, payerName ?? '', comment); } @@ -5946,7 +5943,15 @@ function getReportPreviewMessage( * in {@link getReportPreviewMessage}. */ function getReportPreviewReportActionMessage(params: GetReportPreviewMessageBaseParams, getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']): string { - const {reportOrID, iouReportAction = null, shouldConsiderScanningReceiptOrPendingRoute = false, isPreviewMessageForParentChatReport = false, policy, isForListPreview = false} = params; + const { + reportOrID, + iouReportAction = null, + shouldConsiderScanningReceiptOrPendingRoute = false, + isPreviewMessageForParentChatReport = false, + policy, + isForListPreview = false, + formatPhoneNumber, + } = params; const originalReportAction = params.originalReportAction ?? iouReportAction; const report = typeof reportOrID === 'string' ? getReport(reportOrID, deprecatedAllReports) : reportOrID; const reportActionMessage = getReportActionHtml(iouReportAction); @@ -6025,7 +6030,7 @@ function getReportPreviewReportActionMessage(params: GetReportPreviewMessageBase const policyName = getPolicyName({report: parentReport ?? report, policy}); const payerName = isExpenseReport(report) ? policyName - : getDisplayNameForParticipant({accountID: report.managerID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils}); + : getDisplayNameForParticipant({accountID: report.managerID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber}); const formattedAmount = convertToDisplayStringEnLocale(totalAmount, report.currency, getCurrencyDecimals); @@ -6082,7 +6087,7 @@ function getReportPreviewReportActionMessage(params: GetReportPreviewMessageBase let actualPayerName = report.managerID === deprecatedCurrentUserAccountID && !isForListPreview ? '' - : getDisplayNameForParticipant({accountID: payerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils}); + : getDisplayNameForParticipant({accountID: payerAccountID, shouldUseShortForm: true, formatPhoneNumber}); actualPayerName = actualPayerName && isForListPreview && !isPreviewMessageForParentChatReport ? `${actualPayerName}:` : actualPayerName; const payerDisplayName = isPreviewMessageForParentChatReport ? payerName : actualPayerName; @@ -6115,7 +6120,7 @@ function getReportPreviewReportActionMessage(params: GetReportPreviewMessageBase } if (report.isWaitingOnBankAccount) { - const submitterDisplayName = getDisplayNameForParticipant({accountID: report.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils}) ?? ''; + const submitterDisplayName = getDisplayNameForParticipant({accountID: report.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber}) ?? ''; return `started payment, but is waiting for ${submitterDisplayName} to add a personal bank account.`; } @@ -6144,13 +6149,13 @@ function getReportPreviewReportActionMessage(params: GetReportPreviewMessageBase // We only want to show the actor name in the preview if it's not the current user who took the action const requestorName = lastActorID && lastActorID !== deprecatedCurrentUserAccountID - ? getDisplayNameForParticipant({accountID: lastActorID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils}) + ? getDisplayNameForParticipant({accountID: lastActorID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber}) : ''; return `${requestorName ? `${requestorName}: ` : ''}${amountToDisplay}${comment ? ` for ${comment}` : ''}`; } if (containsNonReimbursable) { - const ownerName = getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils}) ?? ''; + const ownerName = getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber}) ?? ''; return `${ownerName} spent ${formattedAmount}`; } return `${payerName ?? ''} owes ${formattedAmount}${comment ? ` for ${comment}` : ''}`; @@ -6268,7 +6273,7 @@ function getModifiedExpenseOriginalMessage( /** * Get the payee name given a report. */ -function getPayeeName(report: OnyxEntry, translate: LocalizedTranslate): string | undefined { +function getPayeeName(report: OnyxEntry, translate: LocalizedTranslate, formatPhoneNumber: LocaleContextProps['formatPhoneNumber']): string | undefined { if (isEmptyObject(report)) { return undefined; } @@ -6280,7 +6285,7 @@ function getPayeeName(report: OnyxEntry, translate: LocalizedTranslate): if (participantsWithoutCurrentUser.length === 0) { return undefined; } - return getDisplayNameForParticipant({accountID: participantsWithoutCurrentUser.at(0), shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + return getDisplayNameForParticipant({accountID: participantsWithoutCurrentUser.at(0), shouldUseShortForm: true, formatPhoneNumber, translate}); } // TODO: currentUserEmail will be required eventually so this becomes a pure function. Subscribe the data via useOnyx and pass it from the component. Refactor issue: https://github.com/Expensify/App/issues/66412 @@ -6389,6 +6394,7 @@ function getParentNavigationSubtitle( policy: OnyxEntry, conciergeReportID: string | undefined, translate: LocalizedTranslate, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], parentReportName: string | undefined, isParentReportArchived = false, ): ParentNavigationSummaryParams { @@ -6399,8 +6405,7 @@ function getParentNavigationSubtitle( const personalDetails = ownerAccountID ? allPersonalDetails?.[ownerAccountID] : undefined; const login = personalDetails ? personalDetails.login : null; - const reportOwnerDisplayName = - getDisplayNameForParticipant({accountID: ownerAccountID, shouldRemoveDomain: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) || login; + const reportOwnerDisplayName = getDisplayNameForParticipant({accountID: ownerAccountID, shouldRemoveDomain: true, formatPhoneNumber, translate}) || login; if (isExpenseReport(report)) { return { @@ -7890,6 +7895,7 @@ function buildOptimisticSubmittedReportAction( function buildOptimisticReportPreview( chatReport: OnyxInputOrEntry, iouReport: Report, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], comment = '', transaction: OnyxInputOrEntry = null, childReportID?: string, @@ -7897,7 +7903,7 @@ function buildOptimisticReportPreview( delegateAccountIDParam: number | undefined = undefined, ): ReportAction { const hasReceipt = hasReceiptTransactionUtils(transaction); - const message = getReportPreviewReportActionMessage({reportOrID: iouReport}, getCurrencyDecimalsUtil); + const message = getReportPreviewReportActionMessage({reportOrID: iouReport, formatPhoneNumber}, getCurrencyDecimalsUtil); const created = DateUtils.getDBTime(); const reportActorAccountID = (isInvoiceReport(iouReport) || isExpenseReport(iouReport) ? iouReport?.ownerAccountID : iouReport?.managerID) ?? -1; // Falls back to module-level delegateEmail (from Onyx.connect) for callers not yet migrated; will be removed in https://github.com/Expensify/App/issues/66425 @@ -8070,6 +8076,7 @@ function buildOptimisticDetachReceipt(reportID: string | undefined, transactionI function updateReportPreview( iouReport: OnyxEntry, reportPreviewAction: ReportAction, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], isPayRequest = false, comment = '', transaction?: OnyxEntry, @@ -8088,7 +8095,7 @@ function updateReportPreview( } } - const message = getReportPreviewReportActionMessage({reportOrID: iouReport, iouReportAction: reportPreviewAction}, getCurrencyDecimalsUtil); + const message = getReportPreviewReportActionMessage({reportOrID: iouReport, iouReportAction: reportPreviewAction, formatPhoneNumber}, getCurrencyDecimalsUtil); const originalMessage = getOriginalMessage(reportPreviewAction); return { ...reportPreviewAction, diff --git a/src/libs/actions/IOU/MoneyRequestBuilder.ts b/src/libs/actions/IOU/MoneyRequestBuilder.ts index 6bf908bdcce5..8964d0df51e0 100644 --- a/src/libs/actions/IOU/MoneyRequestBuilder.ts +++ b/src/libs/actions/IOU/MoneyRequestBuilder.ts @@ -1616,9 +1616,18 @@ function getMoneyRequestInformation(moneyRequestInformation: MoneyRequestInforma let reportPreviewAction = shouldCreateNewMoneyRequestReport ? null : getReportPreviewAction(chatReport.reportID, iouReport.reportID); if (reportPreviewAction) { - reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, false, comment, optimisticTransaction); + reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, formatPhoneNumber, false, comment, optimisticTransaction); } else { - reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, comment, optimisticTransaction, undefined, optimisticReportPreviewActionID, delegateAccountID); + reportPreviewAction = buildOptimisticReportPreview( + chatReport, + iouReport, + formatPhoneNumber, + comment, + optimisticTransaction, + undefined, + optimisticReportPreviewActionID, + delegateAccountID, + ); chatReport.lastVisibleActionCreated = reportPreviewAction.created; // Generated ReportPreview action is a parent report action of the iou report. diff --git a/src/libs/actions/IOU/PerDiem.ts b/src/libs/actions/IOU/PerDiem.ts index 80f03d9b9a05..440bc11ed236 100644 --- a/src/libs/actions/IOU/PerDiem.ts +++ b/src/libs/actions/IOU/PerDiem.ts @@ -484,9 +484,18 @@ function getPerDiemExpenseInformation(perDiemExpenseInformation: PerDiemExpenseI let reportPreviewAction = shouldCreateNewMoneyRequestReport ? null : getReportPreviewAction(chatReport.reportID, iouReport.reportID); if (reportPreviewAction) { - reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, false, comment, optimisticTransaction); + reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, formatPhoneNumber, false, comment, optimisticTransaction); } else { - reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, comment, optimisticTransaction, undefined, optimisticReportPreviewActionID, delegateAccountID); + reportPreviewAction = buildOptimisticReportPreview( + chatReport, + iouReport, + formatPhoneNumber, + comment, + optimisticTransaction, + undefined, + optimisticReportPreviewActionID, + delegateAccountID, + ); chatReport.lastVisibleActionCreated = reportPreviewAction.created; // Generated ReportPreview action is a parent report action of the iou report. diff --git a/src/libs/actions/IOU/SendInvoice.ts b/src/libs/actions/IOU/SendInvoice.ts index d79eb812a11e..83ed2661f1f5 100644 --- a/src/libs/actions/IOU/SendInvoice.ts +++ b/src/libs/actions/IOU/SendInvoice.ts @@ -714,7 +714,16 @@ function getSendInvoiceInformation({ } // STEP 5: Build optimistic reportActions. - const reportPreviewAction = buildOptimisticReportPreview(chatReport, optimisticInvoiceReport, trimmedComment, optimisticTransaction, undefined, undefined, delegateAccountID); + const reportPreviewAction = buildOptimisticReportPreview( + chatReport, + optimisticInvoiceReport, + formatPhoneNumber, + trimmedComment, + optimisticTransaction, + undefined, + undefined, + delegateAccountID, + ); optimisticInvoiceReport.parentReportActionID = reportPreviewAction.reportActionID; chatReport.lastVisibleActionCreated = reportPreviewAction.created; const [optimisticCreatedActionForChat, optimisticCreatedActionForIOUReport, iouAction, optimisticTransactionThread, optimisticCreatedActionForTransactionThread] = diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index bba490186c3a..d8a6da3a7ad6 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -914,6 +914,7 @@ function completeSplitBill({ delegateAccountID, isTrackIntentUser, sessionEmail, + formatPhoneNumber, }: CompleteSplitBillActionParams) { if (!reportAction) { return; @@ -1122,9 +1123,18 @@ function completeSplitBill({ let oneOnOneReportPreviewAction = getReportPreviewAction(oneOnOneChatReport?.reportID, oneOnOneIOUReport?.reportID); if (oneOnOneReportPreviewAction) { - oneOnOneReportPreviewAction = updateReportPreview(oneOnOneIOUReport, oneOnOneReportPreviewAction); + oneOnOneReportPreviewAction = updateReportPreview(oneOnOneIOUReport, oneOnOneReportPreviewAction, formatPhoneNumber); } else { - oneOnOneReportPreviewAction = buildOptimisticReportPreview(oneOnOneChatReport, oneOnOneIOUReport, '', oneOnOneTransaction, undefined, undefined, delegateAccountID); + oneOnOneReportPreviewAction = buildOptimisticReportPreview( + oneOnOneChatReport, + oneOnOneIOUReport, + formatPhoneNumber, + '', + oneOnOneTransaction, + undefined, + undefined, + delegateAccountID, + ); } const hasViolations = hasViolationsReportUtils(oneOnOneIOUReport.reportID, transactionViolations, sessionAccountID, sessionEmail ?? ''); @@ -1849,9 +1859,18 @@ function createSplitsAndOnyxData({ let oneOnOneReportPreviewAction = getReportPreviewAction(oneOnOneChatReport.reportID, oneOnOneIOUReport.reportID); if (oneOnOneReportPreviewAction) { - oneOnOneReportPreviewAction = updateReportPreview(oneOnOneIOUReport, oneOnOneReportPreviewAction); + oneOnOneReportPreviewAction = updateReportPreview(oneOnOneIOUReport, oneOnOneReportPreviewAction, formatPhoneNumber); } else { - oneOnOneReportPreviewAction = buildOptimisticReportPreview(oneOnOneChatReport, oneOnOneIOUReport, '', oneOnOneTransaction, undefined, undefined, delegateAccountID); + oneOnOneReportPreviewAction = buildOptimisticReportPreview( + oneOnOneChatReport, + oneOnOneIOUReport, + formatPhoneNumber, + '', + oneOnOneTransaction, + undefined, + undefined, + delegateAccountID, + ); } const optimisticPolicyRecentlyUsedCategories = isPolicyExpenseChat ? mergePolicyRecentlyUsedCategories(category, policyRecentlyUsedCategories) : []; diff --git a/src/pages/DynamicReportDetailsPage.tsx b/src/pages/DynamicReportDetailsPage.tsx index 9dbbf321d65c..1bcdf36b6b9b 100644 --- a/src/pages/DynamicReportDetailsPage.tsx +++ b/src/pages/DynamicReportDetailsPage.tsx @@ -272,7 +272,7 @@ function DynamicReportDetailsPage({policy, report, route, reportMetadata, report const isReportArchived = useReportIsArchived(report?.reportID); const isArchivedRoom = useMemo(() => isArchivedNonExpenseReport(report, isReportArchived), [report, isReportArchived]); const shouldDisableRename = useMemo(() => shouldDisableRenameUtil(report, isReportArchived), [report, isReportArchived]); - const parentNavigationSubtitleData = getParentNavigationSubtitle(report, policy, conciergeReportID, translate, derivedParentReportName, isParentReportArchived); + const parentNavigationSubtitleData = getParentNavigationSubtitle(report, policy, conciergeReportID, translate, formatPhoneNumber, derivedParentReportName, isParentReportArchived); const base62ReportID = getBase62ReportID(Number(report.reportID)); const ancestors = useAncestors(report); diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 0c7602499001..d3bb674c5d6b 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -126,7 +126,7 @@ function ShareCodePage({report, policy, backTo}: ShareCodePageProps) { } return ( - getParentNavigationSubtitle(report, policy, conciergeReportID, translate, derivedParentReportName, isParentReportArchived).workspaceName ?? + getParentNavigationSubtitle(report, policy, conciergeReportID, translate, formatPhoneNumber, derivedParentReportName, isParentReportArchived).workspaceName ?? getChatRoomSubtitle(report, policy, conciergeReportID, translate, false, isReportArchived) ); } diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index 2942d4d1a187..7b3652fed520 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -996,7 +996,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const modifyExpenseMessage = Parser.htmlToMarkdown(modifyExpenseMessageWithHTML); Clipboard.setString(modifyExpenseMessage); } else if (isReimbursementDeQueuedOrCanceledAction(reportAction)) { - const displayMessage = getReimbursementDeQueuedOrCanceledActionMessage(translate, reportAction, report?.ownerAccountID, convertToDisplayString); + const displayMessage = getReimbursementDeQueuedOrCanceledActionMessage(translate, formatPhoneNumber, reportAction, report?.ownerAccountID, convertToDisplayString); Clipboard.setString(displayMessage); } else if (isMoneyRequestAction(reportAction)) { const displayMessage = getIOUReportActionDisplayMessage(translate, reportAction, convertToDisplayString, transaction, report, bankAccountList); diff --git a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index f9fe10e5eefd..850ae6a10932 100644 --- a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -158,7 +158,7 @@ function AttachmentPickerWithMenuItems({ const isFocused = useIsFocused(); const theme = useTheme(); const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {calculatePopoverPosition} = usePopoverPosition(); const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null); @@ -270,7 +270,7 @@ function AttachmentPickerWithMenuItems({ [CONST.IOU.TYPE.PAY]: [ { icon: getIconForAction(CONST.IOU.TYPE.SEND, icons), - text: translate('iou.paySomeone', getPayeeName(report, translate)), + text: translate('iou.paySomeone', getPayeeName(report, translate, formatPhoneNumber)), shouldCallAfterModalHide: shouldUseNarrowLayout, sentryLabel: CONST.SENTRY_LABEL.REPORT.ATTACHMENT_PICKER_MENU_PAY_SOMEONE, onSelected: () => { diff --git a/src/pages/inbox/report/actionContents/ReimbursementDeQueuedContent.tsx b/src/pages/inbox/report/actionContents/ReimbursementDeQueuedContent.tsx index 58598d797462..b5af51a31e07 100644 --- a/src/pages/inbox/report/actionContents/ReimbursementDeQueuedContent.tsx +++ b/src/pages/inbox/report/actionContents/ReimbursementDeQueuedContent.tsx @@ -18,10 +18,11 @@ type ReimbursementDeQueuedContentProps = { }; function ReimbursementDeQueuedContent({action, reportOwnerAccountID}: ReimbursementDeQueuedContentProps) { - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {convertToDisplayString} = useCurrencyListActions(); const message = getReimbursementDeQueuedOrCanceledActionMessage( translate, + formatPhoneNumber, action as OnyxEntry>, reportOwnerAccountID, convertToDisplayString, diff --git a/src/pages/iou/request/DistanceRequestStartPage.tsx b/src/pages/iou/request/DistanceRequestStartPage.tsx index fc5bc344dfc5..92f1ce715033 100644 --- a/src/pages/iou/request/DistanceRequestStartPage.tsx +++ b/src/pages/iou/request/DistanceRequestStartPage.tsx @@ -52,7 +52,7 @@ function DistanceRequestStartPage({ defaultSelectedTab = CONST.TAB_REQUEST.DISTANCE_MAP, }: DistanceRequestStartPageProps) { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${getNonEmptyStringOnyxID(route?.params.transactionID)}`); const {policy} = usePolicyForTransaction({transaction, reportPolicyID: report?.policyID, action, iouType}); @@ -76,8 +76,8 @@ function DistanceRequestStartPage({ const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.trackDistance'), [CONST.IOU.TYPE.SUBMIT]: translate('iou.trackDistance'), - [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', getPayeeName(report, translate)), - [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', getPayeeName(report, translate)), + [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', getPayeeName(report, translate, formatPhoneNumber)), + [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', getPayeeName(report, translate, formatPhoneNumber)), [CONST.IOU.TYPE.SPLIT]: translate('iou.splitExpense'), [CONST.IOU.TYPE.SPLIT_EXPENSE]: translate('iou.splitExpense'), [CONST.IOU.TYPE.TRACK]: translate('iou.trackDistance'), diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 9f29e1e22e41..1eb254a3f63a 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -67,7 +67,7 @@ function IOURequestStartPage({ defaultSelectedTab = CONST.TAB_REQUEST.SCAN, }: IOURequestStartPageProps) { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const shouldUseTab = iouType !== CONST.IOU.TYPE.SEND && iouType !== CONST.IOU.TYPE.PAY && iouType !== CONST.IOU.TYPE.INVOICE; const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const [reportDraft] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`); @@ -87,8 +87,8 @@ function IOURequestStartPage({ const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), - [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', getPayeeName(report, translate)), - [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', getPayeeName(report, translate)), + [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', getPayeeName(report, translate, formatPhoneNumber)), + [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', getPayeeName(report, translate, formatPhoneNumber)), [CONST.IOU.TYPE.SPLIT]: translate('iou.splitExpense'), [CONST.IOU.TYPE.SPLIT_EXPENSE]: translate('iou.splitExpense'), [CONST.IOU.TYPE.TRACK]: translate('iou.createExpense'), From 7b8c7be7be31abf3613f02d3427cfb9df4e38253 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 11 Aug 2026 00:44:31 +0430 Subject: [PATCH 02/19] Thread formatPhoneNumber through report preview builders --- src/libs/OptionsListUtils/index.ts | 17 ++++++--- src/libs/actions/IOU/Hold.ts | 5 +++ src/libs/actions/IOU/PayMoneyRequest.ts | 25 +++++++++++-- src/libs/actions/IOU/RejectMoneyRequest.ts | 18 +++++++++- src/libs/actions/IOU/SendMoney.ts | 35 +++++++++++++++++-- src/libs/actions/IOU/TrackExpense.ts | 20 +++++++++-- .../IOU/types/CreateTrackExpenseParams.ts | 1 + src/libs/actions/Policy/Policy.ts | 4 ++- src/libs/actions/Report/index.ts | 17 +++++++-- src/pages/inbox/HeaderView.tsx | 10 +++++- tests/perf-test/ReportUtils.perf-test.ts | 1 + tests/unit/OptionsListUtilsTest.tsx | 1 + tests/unit/SidebarUtilsTest.ts | 6 ++-- 13 files changed, 141 insertions(+), 19 deletions(-) diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 6ad86b41491c..71e9e995e653 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -742,12 +742,13 @@ function getLastMessageTextForReport({ } } else if (isMoneyRequestAction(lastReportAction)) { // Non-React call path: pass the standalone util until this file's own convertToDisplayString threading PR. - const properSchemaForMoneyRequestMessage = getReportPreviewMessage(translate, convertToDisplayStringUtil, { + const properSchemaForMoneyRequestMessage = getReportPreviewMessage(translate, formatPhoneNumberPhoneUtils, convertToDisplayStringUtil, { reportOrID: report, iouReportAction: lastReportAction, shouldConsiderScanningReceiptOrPendingRoute: true, policy: null, isForListPreview: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, }); lastMessageTextFromReport = formatReportLastMessageText(Parser.htmlToText(properSchemaForMoneyRequestMessage)); } else if (isReportPreviewAction(lastReportAction)) { @@ -766,7 +767,7 @@ function getLastMessageTextForReport({ lastMessageTextFromReport = formatReportLastMessageText(reportName); } else { // Non-React call path: pass the standalone util until this file's own convertToDisplayString threading PR. - const reportPreviewMessage = getReportPreviewMessage(translate, convertToDisplayStringUtil, { + const reportPreviewMessage = getReportPreviewMessage(translate, formatPhoneNumberPhoneUtils, convertToDisplayStringUtil, { reportOrID: !isEmptyObject(iouReport) ? iouReport : null, iouReportAction: lastIOUMoneyReportAction ?? lastReportAction, shouldConsiderScanningReceiptOrPendingRoute: true, @@ -774,6 +775,7 @@ function getLastMessageTextForReport({ policy: null, isForListPreview: true, originalReportAction: lastReportAction, + formatPhoneNumber: formatPhoneNumberPhoneUtils, }); lastMessageTextFromReport = formatReportLastMessageText(Parser.htmlToText(reportPreviewMessage)); } @@ -781,7 +783,13 @@ function getLastMessageTextForReport({ lastMessageTextFromReport = getReimbursementQueuedActionMessage({reportAction: lastReportAction, translate, formatPhoneNumber: formatPhoneNumberPhoneUtils, report}); } else if (isReimbursementDeQueuedOrCanceledAction(lastReportAction)) { // Non-React call path: pass the standalone util until this file's own convertToDisplayString threading PR. - lastMessageTextFromReport = getReimbursementDeQueuedOrCanceledActionMessage(translate, lastReportAction, report?.ownerAccountID, convertToDisplayStringUtil); + lastMessageTextFromReport = getReimbursementDeQueuedOrCanceledActionMessage( + translate, + formatPhoneNumberPhoneUtils, + lastReportAction, + report?.ownerAccountID, + convertToDisplayStringUtil, + ); } else if (isDeletedParentAction(lastReportAction) && reportUtilsIsChatReport(report)) { lastMessageTextFromReport = getDeletedParentActionMessageForChatReport(lastReportAction); } else if (isPendingRemove(lastReportAction) && report?.reportID && isThreadParentMessage(lastReportAction, report.reportID)) { @@ -1053,12 +1061,13 @@ function getLastMessageTextForReport({ formatReportLastMessageText( Parser.htmlToText( // Non-React call path: pass the standalone util until this file's own convertToDisplayString threading PR. - getReportPreviewMessage(translate, convertToDisplayStringUtil, { + getReportPreviewMessage(translate, formatPhoneNumberPhoneUtils, convertToDisplayStringUtil, { reportOrID: report, iouReportAction: lastReportAction, shouldConsiderScanningReceiptOrPendingRoute: true, policy: null, isForListPreview: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, }), ), ) || lastVisibleMessage?.lastMessageText; diff --git a/src/libs/actions/IOU/Hold.ts b/src/libs/actions/IOU/Hold.ts index 2abd57421d62..d8603803a5e1 100644 --- a/src/libs/actions/IOU/Hold.ts +++ b/src/libs/actions/IOU/Hold.ts @@ -1,3 +1,5 @@ +import type {LocaleContextProps} from '@components/LocaleContextProvider'; + import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import * as API from '@libs/API'; @@ -665,6 +667,7 @@ function getReportFromHoldRequestsOnyxData({ isApprovalFlow = false, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, }: { chatReport: OnyxTypes.Report; iouReport: OnyxEntry; @@ -675,6 +678,7 @@ function getReportFromHoldRequestsOnyxData({ isApprovalFlow?: boolean; delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }): { optimisticHoldReportID: string; optimisticHoldActionID: string; @@ -734,6 +738,7 @@ function getReportFromHoldRequestsOnyxData({ const optimisticExpenseReportPreview = buildOptimisticReportPreview( chatReport, optimisticExpenseReport, + formatPhoneNumber, getCurrencyDecimals, '', firstHoldTransaction, diff --git a/src/libs/actions/IOU/PayMoneyRequest.ts b/src/libs/actions/IOU/PayMoneyRequest.ts index 9337ea2c52f8..9c0e11c3a957 100644 --- a/src/libs/actions/IOU/PayMoneyRequest.ts +++ b/src/libs/actions/IOU/PayMoneyRequest.ts @@ -1,4 +1,5 @@ import type {PaymentMethod} from '@components/KYCWall/types'; +import type {LocaleContextProps} from '@components/LocaleContextProvider'; import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; @@ -76,6 +77,7 @@ type PayInvoiceArgs = { delegateAccountID: number | undefined; isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type PayMoneyRequestData = { @@ -125,6 +127,7 @@ type PayMoneyRequestFunctionParams = { chatReportActions: OnyxEntry; isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function mergeAdditionalPayOnyxData< @@ -171,6 +174,7 @@ function getPayMoneyRequestParams({ chatReportActions, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }: { initialChatReport: OnyxTypes.Report; iouReport: OnyxEntry; @@ -196,6 +200,7 @@ function getPayMoneyRequestParams({ chatReportActions: OnyxEntry; isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }): PayMoneyRequestData { // TODO: https://github.com/Expensify/App/issues/66512 // eslint-disable-next-line @typescript-eslint/no-deprecated @@ -295,7 +300,7 @@ function getPayMoneyRequestParams({ let optimisticReportPreviewAction = null; const reportPreviewAction = getReportPreviewAction(chatReport.reportID, iouReport?.reportID, chatReportActions); if (reportPreviewAction) { - optimisticReportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, getCurrencyDecimals, true); + optimisticReportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, formatPhoneNumber, getCurrencyDecimals, true); } let optimisticNextStep = null; if (!isInvoiceReport) { @@ -493,7 +498,16 @@ function getPayMoneyRequestParams({ let optimisticHoldActionID; let optimisticHoldReportExpenseActionIDs; if (!full) { - const holdReportOnyxData = getReportFromHoldRequestsOnyxData({chatReport, iouReport, recipient, policy: reportPolicy, betas, delegateAccountID, getCurrencyDecimals}); + const holdReportOnyxData = getReportFromHoldRequestsOnyxData({ + chatReport, + iouReport, + recipient, + policy: reportPolicy, + betas, + delegateAccountID, + formatPhoneNumber, + getCurrencyDecimals, + }); onyxData.optimisticData?.push(...holdReportOnyxData.optimisticData); onyxData.successData?.push(...holdReportOnyxData.successData); @@ -790,6 +804,7 @@ function payMoneyRequest(params: PayMoneyRequestFunctionParams) { chatReportActions, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, } = params; const policyForBillingRestriction = chatReportPolicy ?? (policy?.id === chatReport.policyID ? policy : undefined); if ( @@ -826,6 +841,7 @@ function payMoneyRequest(params: PayMoneyRequestFunctionParams) { chatReportActions, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); // For now, we need to call the PayMoneyRequestWithWallet API since PayMoneyRequest was not updated to work with @@ -849,6 +865,7 @@ function markReportPaymentReceived( chatReportActions: OnyxEntry, isTrackIntentUser: boolean | undefined, getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], ) { if (!chatReport || !iouReport) { return; @@ -881,7 +898,7 @@ function markReportPaymentReceived( optimisticIOUReportAction.message = [{html: receivedPaymentMessage, text: receivedPaymentMessage, isEdited: false, type: CONST.REPORT.MESSAGE.TYPE.COMMENT}]; const reportPreviewAction = getReportPreviewAction(chatReport.reportID, iouReport.reportID, chatReportActions); - const optimisticReportPreviewAction = reportPreviewAction ? updateReportPreview(iouReport, reportPreviewAction, getCurrencyDecimals, true) : null; + const optimisticReportPreviewAction = reportPreviewAction ? updateReportPreview(iouReport, reportPreviewAction, formatPhoneNumber, getCurrencyDecimals, true) : null; const optimisticNextStep = buildOptimisticNextStep({report: iouReport, predictedNextStatus: CONST.REPORT.STATUS_NUM.REIMBURSED, isTrackIntentUser}); const optimisticData: Array> = [ @@ -1032,6 +1049,7 @@ function payInvoice({ delegateAccountID, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }: PayInvoiceArgs) { const recipient = {accountID: invoiceReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID}; const { @@ -1070,6 +1088,7 @@ function payInvoice({ delegateAccountID, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); const paymentSelected = paymentMethodType === CONST.IOU.PAYMENT_TYPE.VBBA ? CONST.IOU.PAYMENT_SELECTED.BBA : CONST.IOU.PAYMENT_SELECTED.PBA; diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index 6c4ef8590a13..c8eb55c550ce 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -1,3 +1,5 @@ +import type {LocaleContextProps} from '@components/LocaleContextProvider'; + import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import * as API from '@libs/API'; @@ -122,6 +124,7 @@ type PrepareRejectMoneyRequestDataParams = { currentUserLogin: string; betas: OnyxEntry; delegateAccountID: number | undefined; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; options?: RejectMoneyRequestOptions; shouldUseBulkAction?: boolean; @@ -136,6 +139,7 @@ function prepareRejectMoneyRequestData({ currentUserLogin, betas, delegateAccountID, + formatPhoneNumber, getCurrencyDecimals, options, shouldUseBulkAction, @@ -516,7 +520,17 @@ function prepareRejectMoneyRequestData({ delegateAccountIDParam: delegateAccountID, }); - reportPreviewAction = buildOptimisticReportPreview(policyExpenseChat, newExpenseReport, getCurrencyDecimals, undefined, transaction, undefined, undefined, delegateAccountID); + reportPreviewAction = buildOptimisticReportPreview( + policyExpenseChat, + newExpenseReport, + formatPhoneNumber, + getCurrencyDecimals, + undefined, + transaction, + undefined, + undefined, + delegateAccountID, + ); movedTransactionAction = buildOptimisticMovedTransactionAction(childReportID, newExpenseReport.reportID); createdIOUReportActionID = iouAction.reportActionID; expenseMovedReportActionID = movedTransactionAction.reportActionID; @@ -940,6 +954,7 @@ function rejectMoneyRequest( currentUserLogin: string, betas: OnyxEntry, delegateAccountID: number | undefined, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], options?: RejectMoneyRequestOptions, ): Route | undefined { @@ -952,6 +967,7 @@ function rejectMoneyRequest( currentUserLogin, betas, delegateAccountID, + formatPhoneNumber, getCurrencyDecimals, options, }); diff --git a/src/libs/actions/IOU/SendMoney.ts b/src/libs/actions/IOU/SendMoney.ts index c485f862ef50..4caca158457c 100644 --- a/src/libs/actions/IOU/SendMoney.ts +++ b/src/libs/actions/IOU/SendMoney.ts @@ -1,4 +1,5 @@ import type {PaymentMethodType} from '@components/KYCWall/types'; +import type {LocaleContextProps} from '@components/LocaleContextProvider'; import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; @@ -83,6 +84,7 @@ function getSendMoneyParams({ currentUserAccountID, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, }: { report: OnyxEntry; quickAction: OnyxEntry; @@ -99,6 +101,7 @@ function getSendMoneyParams({ currentUserAccountID: number; delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }): SendMoneyParamsData { const recipientEmail = addSMSDomainIfPhoneNumber(recipient.login ?? ''); const recipientAccountID = Number(recipient.accountID); @@ -160,7 +163,17 @@ function getSendMoneyParams({ delegateAccountIDParam: delegateAccountID, }); - const reportPreviewAction = buildOptimisticReportPreview(chatReport, optimisticIOUReport, getCurrencyDecimals, undefined, undefined, undefined, undefined, delegateAccountID); + const reportPreviewAction = buildOptimisticReportPreview( + chatReport, + optimisticIOUReport, + formatPhoneNumber, + getCurrencyDecimals, + undefined, + undefined, + undefined, + undefined, + delegateAccountID, + ); // Change the method to set for new reports because it doesn't exist yet, is faster, // and we need the data to be available when we navigate to the chat page @@ -511,6 +524,7 @@ type SendMoneyActionParams = { shouldDeferForSearch?: boolean; delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function executeSendMoney( @@ -518,8 +532,22 @@ function executeSendMoney( paymentMethodType: typeof CONST.IOU.PAYMENT_TYPE.ELSEWHERE | typeof CONST.IOU.PAYMENT_TYPE.EXPENSIFY, writeCommand: typeof WRITE_COMMANDS.SEND_MONEY_ELSEWHERE | typeof WRITE_COMMANDS.SEND_MONEY_WITH_WALLET, ) { - const {report, quickAction, amount, currency, comment, currentUserAccountID, recipient, created, merchant, receipt, optimisticChatReportID, delegateAccountID, getCurrencyDecimals} = - actionParams; + const { + report, + quickAction, + amount, + currency, + comment, + currentUserAccountID, + recipient, + created, + merchant, + receipt, + optimisticChatReportID, + delegateAccountID, + formatPhoneNumber, + getCurrencyDecimals, + } = actionParams; const {shouldStartTracking = true, shouldDeferForSearch = false} = actionParams; const {params, optimisticData, successData, failureData} = getSendMoneyParams({ @@ -537,6 +565,7 @@ function executeSendMoney( optimisticChatReportID, currentUserAccountID, delegateAccountID, + formatPhoneNumber, getCurrencyDecimals, }); if (shouldStartTracking) { diff --git a/src/libs/actions/IOU/TrackExpense.ts b/src/libs/actions/IOU/TrackExpense.ts index 6a6ff4bcc341..db6690567e0c 100644 --- a/src/libs/actions/IOU/TrackExpense.ts +++ b/src/libs/actions/IOU/TrackExpense.ts @@ -1,5 +1,7 @@ import ReceiptGeneric from '@assets/images/receipt-generic.png'; +import type {LocaleContextProps} from '@components/LocaleContextProvider'; + import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import * as API from '@libs/API'; @@ -201,6 +203,7 @@ type GetTrackExpenseInformationParams = { // TODO: Remove optional (?) once all callers are updated in follow-up PRs of https://github.com/Expensify/App/issues/66414 isDraftChatReport?: boolean; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type DeleteTrackExpenseParams = { @@ -868,6 +871,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T currentUserLocalCurrency, policyType, getCurrencyDecimals, + formatPhoneNumber, } = params; const {payeeAccountID = currentUserAccountIDParam, payeeEmail = currentUserEmailParam, participant} = participantParams; const {policy} = policyParams; @@ -1155,9 +1159,19 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T reportPreviewAction = shouldCreateNewMoneyRequestReport ? null : getReportPreviewAction(chatReport.reportID, iouReport.reportID); if (reportPreviewAction) { - reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, getCurrencyDecimals, false, comment, optimisticTransaction); + reportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, formatPhoneNumber, getCurrencyDecimals, false, comment, optimisticTransaction); } else { - reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, getCurrencyDecimals, comment, optimisticTransaction, undefined, undefined, delegateAccountID); + reportPreviewAction = buildOptimisticReportPreview( + chatReport, + iouReport, + formatPhoneNumber, + getCurrencyDecimals, + comment, + optimisticTransaction, + undefined, + undefined, + delegateAccountID, + ); // Generated ReportPreview action is a parent report action of the iou report. // We are setting the iou report's parentReportActionID to display subtitle correctly in IOU page when offline. iouReport.parentReportActionID = reportPreviewAction.reportActionID; @@ -2445,6 +2459,7 @@ function trackExpense(params: CreateTrackExpenseParams) { isDraftChatReport, currentUserLocalCurrency, getCurrencyDecimals, + formatPhoneNumber, } = params; const {accountID: currentUserAccountIDParam, email: currentUserEmailParam = ''} = currentUser; const {participant, payeeAccountID, payeeEmail} = participantParams; @@ -2612,6 +2627,7 @@ function trackExpense(params: CreateTrackExpenseParams) { // Only "Submit to my employer" creates a Submit (submit2026) workspace from a draft; everything else keeps the default (team) type. policyType: action === CONST.IOU.ACTION.SUBMIT && policy?.type === CONST.POLICY.TYPE.SUBMIT ? CONST.POLICY.TYPE.SUBMIT : undefined, getCurrencyDecimals, + formatPhoneNumber, }) ?? {}; const activeReportID = isMoneyRequestReport ? report?.reportID : chatReport?.reportID; const onyxData: TrackedExpenseParams['onyxData'] = trackExpenseInformationOnyxData; diff --git a/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts b/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts index 86475e5dcbce..423e9811d0bc 100644 --- a/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts +++ b/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts @@ -53,6 +53,7 @@ type CreateTrackExpenseParams = { // TODO: Remove optional (?) once all callers are updated in follow-up PRs of https://github.com/Expensify/App/issues/66414 isDraftChatReport?: boolean; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; export type {CreateTrackExpenseParams, TrackExpenseAccountantParams}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 5c8552783f45..efd75cf31dea 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -227,6 +227,7 @@ type CreateWorkspaceFromIOUPaymentOptions = { reportActionsList: OnyxCollection; doesEmployeePersonalDetailExist: boolean; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type PolicyCashExpenseMode = ValueOf; @@ -4309,6 +4310,7 @@ function createWorkspaceFromIOUPayment({ reportActionsList, doesEmployeePersonalDetailExist, getCurrencyDecimals, + formatPhoneNumber, }: CreateWorkspaceFromIOUPaymentOptions): WorkspaceFromIOUCreationData | undefined { // This flow only works for IOU reports if (!iouReport || !ReportUtils.isIOUReportUsingReport(iouReport)) { @@ -4711,7 +4713,7 @@ function createWorkspaceFromIOUPayment({ message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - text: ReportUtils.getReportPreviewReportActionMessage({reportOrID: expenseReport, policy: newWorkspace}, getCurrencyDecimals), + text: ReportUtils.getReportPreviewReportActionMessage({reportOrID: expenseReport, policy: newWorkspace, formatPhoneNumber}, getCurrencyDecimals), }, ], created: DateUtils.getDBTime(), diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 6ecef773055c..03ed10ab2cfd 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4160,6 +4160,7 @@ type BuildNewReportOptimisticDataParams = { isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; reportName?: string; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function buildNewReportOptimisticData({ @@ -4174,6 +4175,7 @@ function buildNewReportOptimisticData({ isTrackIntentUser, getCurrencyDecimals, reportName, + formatPhoneNumber, }: BuildNewReportOptimisticDataParams) { const {accountID, login, email} = ownerPersonalDetails; const timeOfCreation = DateUtils.getDBTime(); @@ -4213,7 +4215,7 @@ function buildNewReportOptimisticData({ pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; - const message = getReportPreviewReportActionMessage({reportOrID: optimisticReportData}, getCurrencyDecimals); + const message = getReportPreviewReportActionMessage({reportOrID: optimisticReportData, formatPhoneNumber}, getCurrencyDecimals); const createReportActionMessage = [ { html: message, @@ -4404,6 +4406,7 @@ function createNewReport( isTrackIntentUser: boolean | undefined, getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], shouldNotifyNewAction = false, + formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], shouldDismissEmptyReportsConfirmation?: boolean, options: {managedCardTransactionID?: string; reportName?: string} = {}, ) { @@ -4424,6 +4427,7 @@ function createNewReport( isTrackIntentUser, getCurrencyDecimals, reportName, + formatPhoneNumber, }); if (shouldDismissEmptyReportsConfirmation) { @@ -5194,6 +5198,7 @@ function buildInviteToRoomOnyxData( key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { participants: newParticipantAccountCleanUp, + pendingAction: null, }, }, { @@ -7462,6 +7467,7 @@ function buildOptimisticChangePolicyData({ reportPreviewAction, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }: { report: Report; parentReport: OnyxEntry; @@ -7477,6 +7483,7 @@ function buildOptimisticChangePolicyData({ reportPreviewAction: OnyxEntry; isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }) { const optimisticData: Array< OnyxUpdate< @@ -7708,7 +7715,7 @@ function buildOptimisticChangePolicyData({ // and set it as a parent of the moved report const policyExpenseChat = optimisticPolicyExpenseChatReport ?? getPolicyExpenseChat(report.ownerAccountID, policy.id); // TODO: delegateAccountIDParam will be threaded in PR 15 (https://github.com/Expensify/App/issues/66425) - const optimisticReportPreviewAction = buildOptimisticReportPreview(policyExpenseChat, report, getCurrencyDecimals, '', null, undefined, undefined, undefined); + const optimisticReportPreviewAction = buildOptimisticReportPreview(policyExpenseChat, report, formatPhoneNumber, getCurrencyDecimals, '', null, undefined, undefined, undefined); const newPolicyExpenseChatReportID = policyExpenseChat?.reportID; @@ -7959,6 +7966,7 @@ function changeReportPolicy({ isTrackIntentUser, getCurrencyDecimals, reportTransactions, + formatPhoneNumber, }: { report: Report; parentReport: OnyxEntry; @@ -7975,6 +7983,7 @@ function changeReportPolicy({ isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; reportTransactions: Transaction[]; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }) { if (!report || !policy || report.policyID === policy.id || !isExpenseReport(report) || shouldBlockChangeReportPolicyForCommuterExclusion(reportTransactions, policy)) { return; @@ -7994,6 +8003,7 @@ function changeReportPolicy({ reportPreviewAction, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); const params = { @@ -8029,6 +8039,7 @@ function changeReportPolicyAndInviteSubmitter({ isTrackIntentUser, getCurrencyDecimals, reportTransactions, + formatPhoneNumber, }: { report: Report; parentReport: OnyxEntry; @@ -8046,6 +8057,7 @@ function changeReportPolicyAndInviteSubmitter({ isTrackIntentUser: boolean | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; reportTransactions: Transaction[]; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }) { if ( !report.reportID || @@ -8108,6 +8120,7 @@ function changeReportPolicyAndInviteSubmitter({ reportPreviewAction, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); const optimisticData = [...optimisticAddMembersData, ...optimisticChangePolicyData]; diff --git a/src/pages/inbox/HeaderView.tsx b/src/pages/inbox/HeaderView.tsx index af843ebc7a26..74ebcc76431b 100644 --- a/src/pages/inbox/HeaderView.tsx +++ b/src/pages/inbox/HeaderView.tsx @@ -180,7 +180,15 @@ function HeaderView({onNavigationMenuButtonClicked, reportID}: HeaderViewProps) ? getReportStatusTooltipTranslation({stateNum: reportHeaderData?.stateNum, statusNum: reportHeaderData?.statusNum, translate}) : undefined; const isParentReportHeaderDataArchived = useReportIsArchived(reportHeaderData?.parentReportID); - const parentNavigationSubtitleData = getParentNavigationSubtitle(parentNavigationReport, policy, conciergeReportID, translate, derivedParentReportName, isParentReportHeaderDataArchived); + const parentNavigationSubtitleData = getParentNavigationSubtitle( + parentNavigationReport, + policy, + conciergeReportID, + translate, + formatPhoneNumber, + derivedParentReportName, + isParentReportHeaderDataArchived, + ); const humanAgentAccountID = getHumanAgentAccountIDFromReportAction(parentReportAction); const humanAgentName = getHumanAgentFirstName(parentReportAction, personalDetails); const reportDescription = StringUtils.lineBreaksToSpaces(Parser.htmlToText(getReportDescription(report))); diff --git a/tests/perf-test/ReportUtils.perf-test.ts b/tests/perf-test/ReportUtils.perf-test.ts index 87e53d449f21..053c7ec61242 100644 --- a/tests/perf-test/ReportUtils.perf-test.ts +++ b/tests/perf-test/ReportUtils.perf-test.ts @@ -157,6 +157,7 @@ describe('ReportUtils', () => { shouldConsiderScanningReceiptOrPendingRoute: shouldConsiderReceiptBeingScanned, isPreviewMessageForParentChatReport, policy, + formatPhoneNumber, }, getCurrencyDecimalsLocal, ), diff --git a/tests/unit/OptionsListUtilsTest.tsx b/tests/unit/OptionsListUtilsTest.tsx index 177431d7062a..bc112624e6ec 100644 --- a/tests/unit/OptionsListUtilsTest.tsx +++ b/tests/unit/OptionsListUtilsTest.tsx @@ -4975,6 +4975,7 @@ describe('OptionsListUtils', () => { policy: null, isForListPreview: true, originalReportAction: reportPreviewAction, + formatPhoneNumber, }, getCurrencyDecimalsLocal, ); diff --git a/tests/unit/SidebarUtilsTest.ts b/tests/unit/SidebarUtilsTest.ts index 1d37c145cec3..f41ca179ca60 100644 --- a/tests/unit/SidebarUtilsTest.ts +++ b/tests/unit/SidebarUtilsTest.ts @@ -43,7 +43,7 @@ import {createSidebarReportsCollection, createSidebarTestData} from '../utils/co import createRandomTransaction from '../utils/collections/transaction'; import createMock from '../utils/createMock'; import * as LHNTestUtils from '../utils/LHNTestUtils'; -import {convertToDisplayString, getCurrencyDecimalsLocal, localeCompare, translateLocal} from '../utils/TestHelper'; +import {convertToDisplayString, getCurrencyDecimalsLocal, localeCompare, translateLocal, formatPhoneNumber} from '../utils/TestHelper'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; @@ -926,7 +926,7 @@ describe('SidebarUtils', () => { participantAccountIDs: [actorAccountID], }, }; - const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, getCurrencyDecimalsLocal, '', transaction); + const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, formatPhoneNumber, getCurrencyDecimalsLocal, '', transaction); await act(async () => { await Onyx.set(ONYXKEYS.SESSION, {accountID: 55555}); @@ -3933,6 +3933,7 @@ describe('SidebarUtils', () => { policy: null, isForListPreview: true, originalReportAction: lastReportPreviewAction, + formatPhoneNumber, }, getCurrencyDecimalsLocal, ); @@ -4047,6 +4048,7 @@ describe('SidebarUtils', () => { policy: null, isForListPreview: true, originalReportAction: lastReportPreviewAction, + formatPhoneNumber, }, getCurrencyDecimalsLocal, ); From a251319ef3ed9886d25c936de98c3a2201d00948 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Wed, 12 Aug 2026 22:48:24 +0430 Subject: [PATCH 03/19] Propagate phone formatting through report preview actions --- src/components/KYCWall/BaseKYCWall.tsx | 3 +- .../MoneyReportHeaderSecondaryActions.tsx | 4 +- .../PayPrimaryAction.tsx | 4 +- .../QuickCreationActionsBar/index.tsx | 3 +- .../PayActionButton.tsx | 4 +- .../ListItem/ActionCell/PayActionCell.tsx | 4 + .../SearchActionsBarCreateButton.tsx | 3 +- src/hooks/useCreateNewReport.tsx | 3 + src/hooks/useHoldMenuSubmit.ts | 3 + src/hooks/useLifecycleActions.tsx | 6 +- src/hooks/useSearchBulkActions.ts | 4 +- src/hooks/useSelectionModePayment.ts | 4 +- src/libs/IOUAmountSubmission.ts | 9 +- src/libs/actions/IOU/Duplicate.ts | 2 + src/libs/actions/IOU/MoneyRequest.ts | 3 + src/libs/actions/IOU/ReportWorkflow.ts | 3 + src/libs/actions/Search.ts | 101 +++++++++++++----- src/pages/Search/EmptySearchView.tsx | 3 +- .../Search/SearchTransactionsChangeReport.tsx | 3 + src/pages/Share/SubmitDetailsPage.tsx | 3 +- .../AttachmentPickerWithMenuItems.tsx | 3 +- .../menuItems/CreateReportMenuItem.tsx | 3 +- src/pages/iou/RejectReasonPage.tsx | 3 +- .../step/DynamicIOURequestEditReport.tsx | 3 + .../step/DynamicIOURequestStepReport.tsx | 3 + ...andleMoneyRequestStepDistanceNavigation.ts | 1 + .../step/confirmation/useExpenseSubmission.ts | 2 + tests/actions/IOU/RequestMoneyTest.ts | 7 ++ tests/actions/IOUTest/HoldTest.ts | 6 +- tests/actions/IOUTest/PayMoneyRequestTest.ts | 19 +++- .../actions/IOUTest/RejectMoneyRequestTest.ts | 31 +++++- tests/actions/IOUTest/SendMoneyTest.ts | 3 +- tests/actions/IOUTest/TrackExpenseTest.ts | 24 +++++ tests/actions/PolicyTest.ts | 6 ++ tests/ui/UnreadIndicatorsTest.tsx | 2 + tests/unit/GoogleTagManagerTest.tsx | 3 +- tests/unit/ReportUtilsTest.ts | 75 +++++++------ 37 files changed, 282 insertions(+), 84 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index f5ee4bfe8c29..8f287f75c603 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -88,7 +88,7 @@ function KYCWall({ ); const [doesSubmitterPersonalDetailExist] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: doesSubmitterPersonalDetailExistSelector}); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const currentUserDetails = useCurrentUserPersonalDetails(); const currentUserAccountID = currentUserDetails.accountID; @@ -221,6 +221,7 @@ function KYCWall({ reportActionsList: filteredReportActions, doesEmployeePersonalDetailExist: doesSubmitterPersonalDetailExist ?? false, getCurrencyDecimals, + formatPhoneNumber, }) ?? {}; if (policyID && iouReport?.policyID) { savePreferredPaymentMethod(iouReport.policyID, policyID, CONST.LAST_PAYMENT_METHOD.IOU, lastPaymentMethod?.[iouReport?.policyID]); diff --git a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx index 1f8fe135f298..c254a9fd2d73 100644 --- a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx +++ b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx @@ -97,7 +97,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo const {isPaidAnimationRunning, isApprovedAnimationRunning, startAnimation, startApprovedAnimation, startSubmittingAnimation} = usePaymentAnimationsContext(); const {openHoldMenu, openPDFDownload, openHoldEducational, openRejectModal} = useMoneyReportHeaderModals(); - const {translate, localeCompare} = useLocalize(); + const {translate, localeCompare, formatPhoneNumber} = useLocalize(); const isInSidePanel = useIsInSidePanel(); const kycWallRef = useContext(KYCWallContext); @@ -216,6 +216,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo chatReportActions: getChatReportActions(payAsBusiness), delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } else { startAnimation(); @@ -243,6 +244,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); if (currentSearchQueryJSON && !isOffline) { search({ diff --git a/src/components/MoneyReportHeaderPrimaryAction/PayPrimaryAction.tsx b/src/components/MoneyReportHeaderPrimaryAction/PayPrimaryAction.tsx index 7c398357739d..8db65025a90f 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/PayPrimaryAction.tsx +++ b/src/components/MoneyReportHeaderPrimaryAction/PayPrimaryAction.tsx @@ -49,7 +49,7 @@ type PayPrimaryActionProps = { function PayPrimaryAction({reportID, chatReportID}: PayPrimaryActionProps) { const {isPaidAnimationRunning, isApprovedAnimationRunning, stopAnimation, startAnimation, startApprovedAnimation} = usePaymentAnimationsContext(); const {isOffline} = useNetwork(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {accountID, email, login: currentUserLogin, localCurrencyCode} = useCurrentUserPersonalDetails(); const delegateAccountID = useDelegateAccountID(); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); @@ -164,6 +164,7 @@ function PayPrimaryAction({reportID, chatReportID}: PayPrimaryActionProps) { chatReportActions: getChatReportActions(payAsBusiness), delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } else { startAnimation(); @@ -189,6 +190,7 @@ function PayPrimaryAction({reportID, chatReportID}: PayPrimaryActionProps) { delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); if (currentSearchQueryJSON && !isOffline) { search({ diff --git a/src/components/Navigation/QuickCreationActionsBar/index.tsx b/src/components/Navigation/QuickCreationActionsBar/index.tsx index d838fd7fd539..01f9e617f35c 100644 --- a/src/components/Navigation/QuickCreationActionsBar/index.tsx +++ b/src/components/Navigation/QuickCreationActionsBar/index.tsx @@ -39,7 +39,7 @@ import {View} from 'react-native'; function QuickCreationActionsBar() { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const icons = useMemoizedLazyExpensifyIcons(['ReceiptPlus', 'DocumentPlus', 'LocationAdd', 'LuggageWithLinesPlus']); const [session] = useOnyx(ONYXKEYS.SESSION); @@ -108,6 +108,7 @@ function QuickCreationActionsBar() { isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, ); // Navigate to the Reports page first so getCreateReportRoute() resolves against diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/PayActionButton.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/PayActionButton.tsx index 97559a5a5e22..f90cf982d229 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/PayActionButton.tsx +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/PayActionButton.tsx @@ -47,7 +47,7 @@ import useReportPreviewActionButtonData from './useReportPreviewActionButtonData function PayActionButton() { const {isOffline} = useNetwork(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const currentUserDetails = useCurrentUserPersonalDetails(); const currentUserAccountID = currentUserDetails.accountID; const currentUserEmail = currentUserDetails.email ?? ''; @@ -122,6 +122,7 @@ function PayActionButton() { chatReportActions: getChatReportActions(payAsBusiness), delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } else { payMoneyRequest({ @@ -146,6 +147,7 @@ function PayActionButton() { delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); } } diff --git a/src/components/Search/SearchList/ListItem/ActionCell/PayActionCell.tsx b/src/components/Search/SearchList/ListItem/ActionCell/PayActionCell.tsx index b268ce3de1cf..c894ba7ce5fa 100644 --- a/src/components/Search/SearchList/ListItem/ActionCell/PayActionCell.tsx +++ b/src/components/Search/SearchList/ListItem/ActionCell/PayActionCell.tsx @@ -4,6 +4,7 @@ import SettlementButton from '@components/SettlementButton'; import type {PaymentActionParams} from '@components/SettlementButton/types'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import {getParticipantsInvoiceReport} from '@hooks/useParticipantsInvoiceReport'; @@ -40,6 +41,7 @@ type PayActionCellProps = { function PayActionCell({isLoading, policyID, reportID, hash, amount, shouldDisablePointerEvents, chatReport}: PayActionCellProps) { const styles = useThemeStyles(); + const {formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals, convertToDisplayString} = useCurrencyListActions(); const {isOffline} = useNetwork(); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); @@ -131,6 +133,7 @@ function PayActionCell({isLoading, policyID, reportID, hash, amount, shouldDisab chatReportActions, delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); return; } @@ -157,6 +160,7 @@ function PayActionCell({isLoading, policyID, reportID, hash, amount, shouldDisab delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); }; diff --git a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx index e8dfa112bf6a..0d7e4d8d8766 100644 --- a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx +++ b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx @@ -40,7 +40,7 @@ import {View} from 'react-native'; function SearchActionsBarCreateButton() { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const expensifyIcons = useMemoizedLazyExpensifyIcons(['Plus', 'Location', 'Document', 'Receipt', 'Coins', 'Cash', 'Transfer', 'MoneyCircle']); const createButtonRef = useRef(null); @@ -92,6 +92,7 @@ function SearchActionsBarCreateButton() { isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, ); Navigation.setNavigationActionToMicrotaskQueue(() => { diff --git a/src/hooks/useCreateNewReport.tsx b/src/hooks/useCreateNewReport.tsx index 30858bc40484..dbfe51b706f2 100644 --- a/src/hooks/useCreateNewReport.tsx +++ b/src/hooks/useCreateNewReport.tsx @@ -10,6 +10,7 @@ import {useCallback} from 'react'; import {useCurrencyListActions} from './useCurrencyList'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; +import useLocalize from './useLocalize'; import useOnyx from './useOnyx'; import usePermissions from './usePermissions'; @@ -19,6 +20,7 @@ import usePermissions from './usePermissions'; */ function useCreateNewReport() { const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const {formatPhoneNumber} = useLocalize(); const {isBetaEnabled} = usePermissions(); const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector}); @@ -43,6 +45,7 @@ function useCreateNewReport() { isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, ); }, diff --git a/src/hooks/useHoldMenuSubmit.ts b/src/hooks/useHoldMenuSubmit.ts index a5d618fa40af..fa5c47711f6c 100644 --- a/src/hooks/useHoldMenuSubmit.ts +++ b/src/hooks/useHoldMenuSubmit.ts @@ -21,6 +21,7 @@ import {personalDetailsLoginSelector} from '@selectors/PersonalDetails'; import {useCurrencyListActions} from './useCurrencyList'; import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; import useDelegateAccountID from './useDelegateAccountID'; +import useLocalize from './useLocalize'; import useOnyx from './useOnyx'; import usePayChatReportActions from './usePayChatReportActions'; import usePermissions from './usePermissions'; @@ -61,6 +62,7 @@ function useHoldMenuSubmit({moneyRequestReport, chatReport, requestType, payment const currentUserDetails = useCurrentUserPersonalDetails(); const {getCurrencyDecimals} = useCurrencyListActions(); const delegateAccountID = useDelegateAccountID(); + const {formatPhoneNumber} = useLocalize(); const hasViolations = hasViolationsReportUtils(moneyRequestReport?.reportID, transactionViolations, currentUserDetails.accountID, currentUserDetails.email ?? ''); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); @@ -127,6 +129,7 @@ function useHoldMenuSubmit({moneyRequestReport, chatReport, requestType, payment delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); } onClose(); diff --git a/src/hooks/useLifecycleActions.tsx b/src/hooks/useLifecycleActions.tsx index e20fae8144db..a9290acff605 100644 --- a/src/hooks/useLifecycleActions.tsx +++ b/src/hooks/useLifecycleActions.tsx @@ -110,7 +110,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); const {isOffline} = useNetwork(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const styles = useThemeStyles(); const {showConfirmModal} = useConfirmModal(); @@ -313,7 +313,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, CONST.IOU.REPORT_ACTION_TYPE.PAY, () => { startAnimation(); - markReportPaymentReceived(chatReport, moneyRequestReport, accountID, email ?? '', chatReportActions, isTrackIntentUser, getCurrencyDecimals); + markReportPaymentReceived(chatReport, moneyRequestReport, accountID, email ?? '', chatReportActions, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber); }, CONST.IOU.PAYMENT_TYPE.ELSEWHERE, ); @@ -321,7 +321,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, } startAnimation(); - markReportPaymentReceived(chatReport, moneyRequestReport, accountID, email ?? '', chatReportActions, isTrackIntentUser, getCurrencyDecimals); + markReportPaymentReceived(chatReport, moneyRequestReport, accountID, email ?? '', chatReportActions, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber); }, }, [CONST.REPORT.SECONDARY_ACTIONS.UNAPPROVE]: { diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index ca915e7755a1..4f0cd4b25847 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -377,7 +377,7 @@ function getChatReportForBulkPay( } function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { - const {translate, localeCompare} = useLocalize(); + const {translate, localeCompare, formatPhoneNumber} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); const {isOffline} = useNetwork(); @@ -1366,6 +1366,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { chatReportActions: allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${payChatReportID}`], delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); paidReportCount += 1; continue; @@ -1396,6 +1397,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); paidReportCount += 1; } diff --git a/src/hooks/useSelectionModePayment.ts b/src/hooks/useSelectionModePayment.ts index 0c42b21a9f1a..ba154bfa9558 100644 --- a/src/hooks/useSelectionModePayment.ts +++ b/src/hooks/useSelectionModePayment.ts @@ -79,7 +79,7 @@ function useSelectionModePayment({ onPaid, confirmApproval, }: UseSelectionModePaymentParams) { - const {translate, localeCompare} = useLocalize(); + const {translate, localeCompare, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {isOffline} = useNetwork(); const {isBetaEnabled} = usePermissions(); @@ -207,6 +207,7 @@ function useSelectionModePayment({ chatReportActions: getChatReportActions(payAsBusiness), delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } else { payMoneyRequest({ @@ -231,6 +232,7 @@ function useSelectionModePayment({ delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); refreshSearchAfterReportAction({ currentSearchQueryJSON, diff --git a/src/libs/IOUAmountSubmission.ts b/src/libs/IOUAmountSubmission.ts index a3f6d7636bcc..5177bd694904 100644 --- a/src/libs/IOUAmountSubmission.ts +++ b/src/libs/IOUAmountSubmission.ts @@ -1,4 +1,4 @@ -import type {LocalizedTranslate} from '@components/LocaleContextProvider'; +import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider'; import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; @@ -106,6 +106,7 @@ type SubmitAmountArgs = { ownerBillingGracePeriodEnd: OnyxEntry; conciergeReportID: OnyxEntry; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; /** @@ -265,7 +266,7 @@ function buildReportParticipants(args: SubmitAmountArgs) { type ParticipantOption = ReturnType[number]; function submitSkipConfirmationPayment(args: SubmitAmountArgs, ctx: SubmitAmountContext, participants: ParticipantOption[]): void { - const {report, selectedCurrency, paymentMethod, quickAction, delegateAccountID, getCurrencyDecimals} = args; + const {report, selectedCurrency, paymentMethod, quickAction, delegateAccountID, getCurrencyDecimals, formatPhoneNumber} = args; const {currentUserAccountID, newAmount: backendAmount} = ctx; const {optimisticChatReportID, chatReportID} = resolveOptimisticChatReportID([participants.at(0)?.accountID ?? CONST.DEFAULT_NUMBER_ID, currentUserAccountID], report); const sendMoneyParams = { @@ -283,7 +284,7 @@ function submitSkipConfirmationPayment(args: SubmitAmountArgs, ctx: SubmitAmount }; const executeSendMoneyWrite = (overrides?: {shouldDeferForSearch?: boolean}) => { - const mergedParams = {...sendMoneyParams, ...overrides}; + const mergedParams = {...sendMoneyParams, ...overrides, formatPhoneNumber}; if (paymentMethod === CONST.IOU.PAYMENT_TYPE.EXPENSIFY) { sendMoneyWithWallet(mergedParams); } else { @@ -329,6 +330,7 @@ function submitSkipConfirmationExpense(args: SubmitAmountArgs, ctx: SubmitAmount currentUserPersonalDetails, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, } = args; const {currentUserAccountID, currentUserEmail, existingTransactionID, isASAPSubmitBetaEnabled, newAmount: backendAmount} = ctx; @@ -376,6 +378,7 @@ function submitSkipConfirmationExpense(args: SubmitAmountArgs, ctx: SubmitAmount delegateAccountID, reportActionsList: undefined, getCurrencyDecimals, + formatPhoneNumber, }); } else { const existingTransactionDraft = existingTransactionID ? transactionDrafts?.[existingTransactionID] : undefined; diff --git a/src/libs/actions/IOU/Duplicate.ts b/src/libs/actions/IOU/Duplicate.ts index d0aace14ff25..e5b70be3fe30 100644 --- a/src/libs/actions/IOU/Duplicate.ts +++ b/src/libs/actions/IOU/Duplicate.ts @@ -910,6 +910,7 @@ function duplicateExpenseTransaction({ currentUserLocalCurrency, delegateAccountID, reportActionsList: undefined, + formatPhoneNumber, }; return trackExpense(trackExpenseParams); } @@ -1007,6 +1008,7 @@ function duplicateReport({ isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, undefined, { reportName: newReportName, diff --git a/src/libs/actions/IOU/MoneyRequest.ts b/src/libs/actions/IOU/MoneyRequest.ts index 340f7c51b153..8aacd02ddc86 100644 --- a/src/libs/actions/IOU/MoneyRequest.ts +++ b/src/libs/actions/IOU/MoneyRequest.ts @@ -102,6 +102,7 @@ type CreateTransactionParams = { isTrackIntentUser: boolean | undefined; delegateAccountID: number | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type SetMoneyRequestCommuterExclusionFieldsParams = { @@ -146,6 +147,7 @@ function createTransaction({ isTrackIntentUser, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, }: CreateTransactionParams) { const draftTransactionIDs = Object.keys(allTransactionDrafts ?? {}); @@ -209,6 +211,7 @@ function createTransaction({ delegateAccountID, reportActionsList: undefined, getCurrencyDecimals, + formatPhoneNumber, }); } else { const existingTransactionID = getExistingTransactionID(transaction?.linkedTrackedExpenseReportAction); diff --git a/src/libs/actions/IOU/ReportWorkflow.ts b/src/libs/actions/IOU/ReportWorkflow.ts index de9551cd17dd..9682a0484763 100644 --- a/src/libs/actions/IOU/ReportWorkflow.ts +++ b/src/libs/actions/IOU/ReportWorkflow.ts @@ -117,6 +117,7 @@ type ApproveMoneyRequestFunctionParams = { additionalOnyxData?: AdditionalPayOnyxData; shouldPlaySuccessSound?: boolean; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type SubmitReportFunctionParams = { @@ -466,6 +467,7 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { shouldPlaySuccessSound = true, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, } = params; if (!expenseReport) { return; @@ -749,6 +751,7 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { betas, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, }); optimisticData.push(...holdReportOnyxData.optimisticData); diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 4f6b670a728a..2ec55a20d833 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -231,6 +231,7 @@ type HandleActionButtonPressParams = { isTrackIntentUser: boolean | undefined; conciergeChat: OnyxEntry; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function handleActionButtonPress({ @@ -270,6 +271,7 @@ function handleActionButtonPress({ isTrackIntentUser, conciergeChat, getCurrencyDecimals, + formatPhoneNumber, }: HandleActionButtonPressParams) { // The transactionIDList is needed to handle actions taken on `status:""` where transactions on single expense reports can be approved/paid. // We need the transactionID to display the loading indicator for that list item's action. @@ -323,6 +325,7 @@ function handleActionButtonPress({ isTrackIntentUser, conciergeChat, getCurrencyDecimals, + formatPhoneNumber, }); return; case CONST.SEARCH.ACTION_TYPES.APPROVE: @@ -356,6 +359,7 @@ function handleActionButtonPress({ isTrackIntentUser, ownerLogin: submitterLogin, getCurrencyDecimals, + formatPhoneNumber, }); return; case CONST.SEARCH.ACTION_TYPES.SUBMIT: { @@ -532,6 +536,7 @@ type GetPayActionCallbackParams = { isTrackIntentUser: boolean | undefined; conciergeChat: OnyxEntry; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function getPayActionCallback({ @@ -561,6 +566,7 @@ function getPayActionCallback({ isTrackIntentUser, conciergeChat, getCurrencyDecimals, + formatPhoneNumber, }: GetPayActionCallbackParams) { const lastPolicyPaymentMethod = getLastPolicyPaymentMethod(item.policyID, personalPolicyID, lastPaymentMethod, getReportType(item.reportID)); @@ -611,6 +617,7 @@ function getPayActionCallback({ isTrackIntentUser, conciergeChat, getCurrencyDecimals, + formatPhoneNumber, }); } @@ -632,6 +639,7 @@ type GetApproveActionCallbackParams = { isTrackIntentUser: boolean | undefined; ownerLogin: string | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function getApproveActionCallback({ @@ -652,6 +660,7 @@ function getApproveActionCallback({ isTrackIntentUser, ownerLogin, getCurrencyDecimals, + formatPhoneNumber, }: GetApproveActionCallbackParams) { if (!item.reportID) { return; @@ -680,6 +689,7 @@ function getApproveActionCallback({ additionalOnyxData: getSearchApproveOnyxData(hash, item.reportID, currentSearchKey), isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); } @@ -1418,18 +1428,31 @@ function exportToIntegrationOnSearch(hash: number, reportIDs: string[], connecti }); } -function rejectMoneyRequestInBulk( - reportID: string, - comment: string, - policy: OnyxEntry, - transactionIDs: string[], - currentUserAccountIDParam: number, - currentUserLogin: string, - betas: OnyxEntry, - delegateAccountID: number | undefined, - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], - hash?: number, -) { +function rejectMoneyRequestInBulk({ + reportID, + comment, + policy, + transactionIDs, + currentUserAccountIDParam, + currentUserLogin, + betas, + delegateAccountID, + getCurrencyDecimals, + hash, + formatPhoneNumber, +}: { + reportID: string; + comment: string; + policy: OnyxEntry; + transactionIDs: string[]; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + hash?: number; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; +}) { const optimisticData: Array> = []; const finallyData: Array> = []; const successData: RejectMoneyRequestData['successData'] = []; @@ -1458,6 +1481,7 @@ function rejectMoneyRequestInBulk( delegateAccountID, getCurrencyDecimals, shouldUseBulkAction: true, + formatPhoneNumber, }); if (data) { optimisticData.push(...data.optimisticData); @@ -1486,18 +1510,31 @@ type TransactionReportInfo = { reportID?: string; }; -function rejectMoneyRequestsOnSearch( - hash: number, - selectedTransactions: Record, - comment: string, - allPolicies: OnyxCollection, - allReports: OnyxCollection, - currentUserAccountIDParam: number, - currentUserLogin: string, - betas: OnyxEntry, - delegateAccountID: number | undefined, - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], -) { +function rejectMoneyRequestsOnSearch({ + hash, + selectedTransactions, + comment, + allPolicies, + allReports, + currentUserAccountIDParam, + currentUserLogin, + betas, + delegateAccountID, + getCurrencyDecimals, + formatPhoneNumber, +}: { + hash: number; + selectedTransactions: Record; + comment: string; + allPolicies: OnyxCollection; + allReports: OnyxCollection; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; +}) { const transactionIDs = Object.keys(selectedTransactions); const transactionsByReport = transactionIDs.reduce>((acc, transactionID) => { @@ -1529,7 +1566,19 @@ function rejectMoneyRequestsOnSearch( const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]; const isPolicyDelayedSubmissionEnabled = policy ? isDelayedSubmissionEnabled(policy) : false; if (isPolicyDelayedSubmissionEnabled && areAllExpensesSelected) { - rejectMoneyRequestInBulk(reportID, comment, policy, selectedTransactionIDs, currentUserAccountIDParam, currentUserLogin, betas, delegateAccountID, getCurrencyDecimals, hash); + rejectMoneyRequestInBulk({ + reportID, + comment, + policy, + transactionIDs: selectedTransactionIDs, + currentUserAccountIDParam, + currentUserLogin, + betas, + delegateAccountID, + formatPhoneNumber, + getCurrencyDecimals, + hash, + }); } else { // Share a single destination ID across all rejections from the same source report const sharedRejectedToReportID = generateReportID(); @@ -1538,7 +1587,7 @@ function rejectMoneyRequestsOnSearch( existingRejectedReport = nextRejectedReport; }; for (const transactionID of selectedTransactionIDs) { - rejectMoneyRequest(transactionID, reportID, comment, policy, currentUserAccountIDParam, currentUserLogin, betas, delegateAccountID, getCurrencyDecimals, { + rejectMoneyRequest(transactionID, reportID, comment, policy, currentUserAccountIDParam, currentUserLogin, betas, delegateAccountID, formatPhoneNumber, getCurrencyDecimals, { sharedRejectedToReportID, existingRejectedReport, setExistingRejectedReport, diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index b927372615b0..5cc688f3ee2a 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -136,7 +136,7 @@ function EmptySearchViewContent({ onScroll, contentContainerStyle, }: EmptySearchViewContentProps) { - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const timezone = useCurrentTimezone(); const styles = useThemeStyles(); const isInLandscapeMode = useIsInLandscapeMode(); @@ -182,6 +182,7 @@ function EmptySearchViewContent({ isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, ); Navigation.setNavigationActionToMicrotaskQueue(() => { diff --git a/src/pages/Search/SearchTransactionsChangeReport.tsx b/src/pages/Search/SearchTransactionsChangeReport.tsx index d8d06ae4252d..df173cf19ede 100644 --- a/src/pages/Search/SearchTransactionsChangeReport.tsx +++ b/src/pages/Search/SearchTransactionsChangeReport.tsx @@ -5,6 +5,7 @@ import type {ListItem} from '@components/SelectionList/types'; import useConditionalCreateEmptyReportConfirmation from '@hooks/useConditionalCreateEmptyReportConfirmation'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useHasPerDiemTransactions from '@hooks/useHasPerDiemTransactions'; +import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; import usePersonalPolicy from '@hooks/usePersonalPolicy'; @@ -37,6 +38,7 @@ type TransactionGroupListItem = ListItem & { }; function SearchTransactionsChangeReport() { + const {formatPhoneNumber} = useLocalize(); const {selectedTransactions} = useSearchSelectionContext(); const {clearSelectedTransactions} = useSearchSelectionActions(); const {currentSearchResults} = useSearchResultsContext(); @@ -159,6 +161,7 @@ function SearchTransactionsChangeReport() { isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, {managedCardTransactionID}, ); diff --git a/src/pages/Share/SubmitDetailsPage.tsx b/src/pages/Share/SubmitDetailsPage.tsx index a74b6afef2dc..c8e9a0b85ff3 100644 --- a/src/pages/Share/SubmitDetailsPage.tsx +++ b/src/pages/Share/SubmitDetailsPage.tsx @@ -83,7 +83,7 @@ function SubmitDetailsPage({ }, }: ShareDetailsPageProps) { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const delegateAccountID = useDelegateAccountID(); const [unknownUserDetails] = useOnyx(ONYXKEYS.SHARE_UNKNOWN_USER_DETAILS); @@ -416,6 +416,7 @@ function SubmitDetailsPage({ currentUserLocalCurrency: currentUserPersonalDetails.localCurrencyCode ?? CONST.CURRENCY.USD, delegateAccountID, reportActionsList: undefined, + formatPhoneNumber, }); } else { const existingTransactionDraft = existingTransactionID ? transactionDrafts?.[existingTransactionID] : undefined; diff --git a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index 850ae6a10932..60b46fa0af0c 100644 --- a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -216,6 +216,7 @@ function AttachmentPickerWithMenuItems({ isTrackIntentUser, getCurrencyDecimals, true, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, ), true, @@ -226,7 +227,7 @@ function AttachmentPickerWithMenuItems({ if (shouldShowEmptyReportConfirmation) { openCreateReportConfirmation(); } else { - createNewReport(currentUserPersonalDetails, isASAPSubmitBetaEnabled, hasViolations, policy, betas, isTrackIntentUser, getCurrencyDecimals, true, false); + createNewReport(currentUserPersonalDetails, isASAPSubmitBetaEnabled, hasViolations, policy, betas, isTrackIntentUser, getCurrencyDecimals, true, formatPhoneNumber, false); } }; diff --git a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx index 79bc4d833aef..10e323f6d403 100644 --- a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx +++ b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx @@ -55,7 +55,7 @@ const chatEnabledPaidGroupPoliciesSelector = (policies: OnyxCollection; function RejectReasonPage({route}: RejectReasonPageProps) { - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {transactionID, reportID, backTo} = route.params; @@ -62,6 +62,7 @@ function RejectReasonPage({route}: RejectReasonPageProps) { currentUserLogin ?? '', betas, delegateAccountID, + formatPhoneNumber, getCurrencyDecimals, ); removeTransaction(transactionID); diff --git a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx index 9e432f26c692..8421d0b97ef4 100644 --- a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx +++ b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx @@ -7,6 +7,7 @@ import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useHasPerDiemTransactions from '@hooks/useHasPerDiemTransactions'; +import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; import usePersonalPolicy from '@hooks/usePersonalPolicy'; @@ -49,6 +50,7 @@ type TransactionGroupListItem = ListItem & { type DynamicIOURequestEditReportProps = WithWritableReportOrNotFoundProps; function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) { + const {formatPhoneNumber} = useLocalize(); const {reportID, action, shouldTurnOffSelectionMode, transactionID: transactionIDFromParams} = route.params; const backPath = useDynamicBackPath(DYNAMIC_ROUTES.MONEY_REQUEST_EDIT_REPORT.path); const {selectedTransactionIDs} = useSearchSelectionContext(); @@ -168,6 +170,7 @@ function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, {managedCardTransactionID}, ); diff --git a/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx b/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx index fcb822ed6927..be6356fa411a 100644 --- a/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx +++ b/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx @@ -5,6 +5,7 @@ import type {ListItem} from '@components/SelectionList/types'; import useConditionalCreateEmptyReportConfirmation from '@hooks/useConditionalCreateEmptyReportConfirmation'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; +import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useOptimisticDraftTransactions from '@hooks/useOptimisticDraftTransactions'; import usePermissions from '@hooks/usePermissions'; @@ -54,6 +55,7 @@ const getIOUActionsSelector = (actions: OnyxEntry): ReportAction[ }; function DynamicIOURequestStepReport({route, transaction}: DynamicIOURequestStepReportProps) { + const {formatPhoneNumber} = useLocalize(); const {action, iouType, transactionID, reportID: reportIDFromRoute, reportActionID} = route.params; const backPath = useDynamicBackPath(DYNAMIC_ROUTES.MONEY_REQUEST_STEP_REPORT.path); const isUnreported = transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID; @@ -174,6 +176,7 @@ function DynamicIOURequestStepReport({route, transaction}: DynamicIOURequestStep isTrackIntentUser, getCurrencyDecimals, false, + formatPhoneNumber, shouldDismissEmptyReportsConfirmation, {managedCardTransactionID: isUnreportedManagedCardTransaction ? transactionID : undefined}, ); diff --git a/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts b/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts index e4a1278efee4..188551bc87f9 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts +++ b/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts @@ -329,6 +329,7 @@ function handleMoneyRequestStepDistanceNavigation({ delegateAccountID, reportActionsList: undefined, getCurrencyDecimals, + formatPhoneNumber, }); cleanupAfterSkipConfirmSubmit(overrides.shouldHandleNavigation, { report, diff --git a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts index 1fd7009d8480..755b68d8ba97 100644 --- a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts +++ b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts @@ -798,6 +798,7 @@ function useExpenseSubmission(params: UseExpenseSubmissionParams) { reportActionsList: policyExpenseChatReportActions, currentUserLocalCurrency: currentUserPersonalDetails.localCurrencyCode ?? CONST.CURRENCY.USD, delegateAccountID, + formatPhoneNumber, }); } performPostBatchCleanup({ @@ -1192,6 +1193,7 @@ function useExpenseSubmission(params: UseExpenseSubmissionParams) { shouldStartTracking, shouldDeferForSearch, delegateAccountID, + formatPhoneNumber, }; if (paymentMethod === CONST.IOU.PAYMENT_TYPE.ELSEWHERE) { diff --git a/tests/actions/IOU/RequestMoneyTest.ts b/tests/actions/IOU/RequestMoneyTest.ts index ec00fb0699e1..16548a09e9f8 100644 --- a/tests/actions/IOU/RequestMoneyTest.ts +++ b/tests/actions/IOU/RequestMoneyTest.ts @@ -1294,6 +1294,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); mockFetch?.resume?.(); @@ -1367,6 +1368,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1932,6 +1934,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -2774,6 +2777,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -2844,6 +2848,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3089,6 +3094,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3140,6 +3146,7 @@ describe('actions/IOU', () => { currentUserLocalCurrency: 'USD', isTrackIntentUser: false, delegateAccountID: undefined, + formatPhoneNumber, }; }; diff --git a/tests/actions/IOUTest/HoldTest.ts b/tests/actions/IOUTest/HoldTest.ts index 4271a73c7277..381a72845afb 100644 --- a/tests/actions/IOUTest/HoldTest.ts +++ b/tests/actions/IOUTest/HoldTest.ts @@ -25,7 +25,7 @@ import Onyx from 'react-native-onyx'; import type {MockFetch} from '../../utils/TestHelper'; import createRandomPolicy from '../../utils/collections/policies'; -import {getCurrencyDecimalsLocal, getGlobalFetchMock} from '../../utils/TestHelper'; +import {getCurrencyDecimalsLocal, getGlobalFetchMock, formatPhoneNumber} from '../../utils/TestHelper'; import waitForBatchedUpdates from '../../utils/waitForBatchedUpdates'; const topMostReportID = '23423423'; @@ -683,6 +683,7 @@ describe('actions/IOU/Hold', () => { delegateAccountID: undefined, betas: [], getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); const totalsUpdate = result.optimisticData.find((entry) => entry.onyxMethod === Onyx.METHOD.MERGE && entry.key === `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`); expect(totalsUpdate).toBeDefined(); @@ -710,6 +711,7 @@ describe('actions/IOU/Hold', () => { delegateAccountID: undefined, betas: [], getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); const restorationEntries = result.failureData.filter( (entry) => entry.onyxMethod === Onyx.METHOD.MERGE && entry.key === `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, @@ -742,6 +744,7 @@ describe('actions/IOU/Hold', () => { delegateAccountID: undefined, betas: [], getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); const totalsUpdates = result.optimisticData.filter((entry) => { const value = entry.value as Partial | undefined; @@ -771,6 +774,7 @@ describe('actions/IOU/Hold', () => { delegateAccountID: undefined, betas: [], getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); const totalsUpdates = result.optimisticData.filter((entry) => { const value = entry.value as Partial | undefined; diff --git a/tests/actions/IOUTest/PayMoneyRequestTest.ts b/tests/actions/IOUTest/PayMoneyRequestTest.ts index a030fa24ef8f..25a2af8de063 100644 --- a/tests/actions/IOUTest/PayMoneyRequestTest.ts +++ b/tests/actions/IOUTest/PayMoneyRequestTest.ts @@ -35,7 +35,7 @@ import createRandomReportAction from '../../utils/collections/reportActions'; import {createRandomReport} from '../../utils/collections/reports'; import createRandomTransaction from '../../utils/collections/transaction'; import getOnyxValue from '../../utils/getOnyxValue'; -import {getCurrencyDecimalsLocal, getGlobalFetchMock, getOnyxData, translateLocal} from '../../utils/TestHelper'; +import {getCurrencyDecimalsLocal, getGlobalFetchMock, getOnyxData, translateLocal, formatPhoneNumber} from '../../utils/TestHelper'; import waitForBatchedUpdates from '../../utils/waitForBatchedUpdates'; const topMostReportID = '23423423'; @@ -263,6 +263,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -478,6 +479,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -649,6 +651,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -706,6 +709,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -793,6 +797,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: DELEGATE_ACCOUNT_ID, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -881,6 +886,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -982,6 +988,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); const newExpenseReport = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${newExpenseReportID}`); @@ -1023,6 +1030,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1077,6 +1085,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1174,7 +1183,7 @@ describe('actions/IOU/PayMoneyRequest', () => { mockFetch?.pause?.(); - markReportPaymentReceived(chatReport, reimbursedReport, currentUserAccountID, currentUserEmail, mockChatReportActions, false, getCurrencyDecimalsLocal); + markReportPaymentReceived(chatReport, reimbursedReport, currentUserAccountID, currentUserEmail, mockChatReportActions, false, getCurrencyDecimalsLocal, formatPhoneNumber); await waitForBatchedUpdates(); const updatedChatReport = await new Promise>((resolve) => { @@ -1247,6 +1256,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1317,6 +1327,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1377,6 +1388,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1417,6 +1429,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1548,6 +1561,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -1929,6 +1943,7 @@ describe('actions/IOU/PayMoneyRequest', () => { delegateAccountID: undefined, isTrackIntentUser: false, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); } await waitForBatchedUpdates(); diff --git a/tests/actions/IOUTest/RejectMoneyRequestTest.ts b/tests/actions/IOUTest/RejectMoneyRequestTest.ts index 7a3774da25b2..fb6f5db9680d 100644 --- a/tests/actions/IOUTest/RejectMoneyRequestTest.ts +++ b/tests/actions/IOUTest/RejectMoneyRequestTest.ts @@ -22,7 +22,7 @@ import createRandomPolicy from '../../utils/collections/policies'; import {createRandomReport} from '../../utils/collections/reports'; import createRandomTransaction from '../../utils/collections/transaction'; import getOnyxValue from '../../utils/getOnyxValue'; -import {getCurrencyDecimalsLocal, getGlobalFetchMock, getOnyxData} from '../../utils/TestHelper'; +import {getCurrencyDecimalsLocal, getGlobalFetchMock, getOnyxData, formatPhoneNumber} from '../../utils/TestHelper'; import waitForBatchedUpdates from '../../utils/waitForBatchedUpdates'; jest.mock('@src/libs/Navigation/Navigation', () => ({ @@ -163,6 +163,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { TEST_USER_EMAIL, [CONST.BETAS.ALL], undefined, + formatPhoneNumber, getCurrencyDecimalsLocal, ); @@ -180,7 +181,18 @@ describe('actions/IOU/RejectMoneyRequest', () => { if (!transaction?.transactionID || !iouReport?.reportID) { throw new Error('Required transaction or report data is missing'); } - rejectMoneyRequest(transaction.transactionID, iouReport.reportID, comment, policy, TEST_USER_ACCOUNT_ID, TEST_USER_EMAIL, [CONST.BETAS.ALL], undefined, getCurrencyDecimalsLocal); + rejectMoneyRequest( + transaction.transactionID, + iouReport.reportID, + comment, + policy, + TEST_USER_ACCOUNT_ID, + TEST_USER_EMAIL, + [CONST.BETAS.ALL], + undefined, + formatPhoneNumber, + getCurrencyDecimalsLocal, + ); await waitForBatchedUpdates(); // Then: Verify violation is added @@ -236,7 +248,18 @@ describe('actions/IOU/RejectMoneyRequest', () => { if (!transaction?.transactionID || !iouReport?.reportID) { throw new Error('Required transaction or report data is missing'); } - rejectMoneyRequest(transaction.transactionID, iouReport.reportID, comment, policy, TEST_USER_ACCOUNT_ID, TEST_USER_EMAIL, [CONST.BETAS.ALL], undefined, getCurrencyDecimalsLocal); + rejectMoneyRequest( + transaction.transactionID, + iouReport.reportID, + comment, + policy, + TEST_USER_ACCOUNT_ID, + TEST_USER_EMAIL, + [CONST.BETAS.ALL], + undefined, + formatPhoneNumber, + getCurrencyDecimalsLocal, + ); await waitForBatchedUpdates(); // Then: createdIOUReportActionID shouldn't be undefined @@ -284,6 +307,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { TEST_USER_EMAIL, [CONST.BETAS.ALL], undefined, + formatPhoneNumber, getCurrencyDecimalsLocal, { sharedRejectedToReportID, @@ -301,6 +325,7 @@ describe('actions/IOU/RejectMoneyRequest', () => { TEST_USER_EMAIL, [CONST.BETAS.ALL], undefined, + formatPhoneNumber, getCurrencyDecimalsLocal, { sharedRejectedToReportID, diff --git a/tests/actions/IOUTest/SendMoneyTest.ts b/tests/actions/IOUTest/SendMoneyTest.ts index c1fc34aea282..8dd7c59d8da6 100644 --- a/tests/actions/IOUTest/SendMoneyTest.ts +++ b/tests/actions/IOUTest/SendMoneyTest.ts @@ -11,7 +11,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import Onyx from 'react-native-onyx'; -import {getCurrencyDecimalsLocal, getGlobalFetchMock} from '../../utils/TestHelper'; +import {getCurrencyDecimalsLocal, getGlobalFetchMock, formatPhoneNumber} from '../../utils/TestHelper'; import waitForBatchedUpdates from '../../utils/waitForBatchedUpdates'; const topMostReportID = '23423423'; @@ -117,6 +117,7 @@ describe('actions/IOU/SendMoney', () => { recipient: {accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}, delegateAccountID: DELEGATE_ACCOUNT_ID, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); diff --git a/tests/actions/IOUTest/TrackExpenseTest.ts b/tests/actions/IOUTest/TrackExpenseTest.ts index cad5927ec025..7a44b1ed6554 100644 --- a/tests/actions/IOUTest/TrackExpenseTest.ts +++ b/tests/actions/IOUTest/TrackExpenseTest.ts @@ -213,6 +213,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -340,6 +341,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); await mockFetch?.resume?.(); @@ -450,6 +452,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); await mockFetch?.resume?.(); @@ -545,6 +548,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -605,6 +609,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -691,6 +696,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -751,6 +757,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -841,6 +848,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -901,6 +909,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -988,6 +997,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1048,6 +1058,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1154,6 +1165,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1214,6 +1226,7 @@ describe('actions/IOU/TrackExpense', () => { isSelfTourViewed: false, currentUserLocalCurrency: undefined, delegateAccountID: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1279,6 +1292,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }; } @@ -1542,6 +1556,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1634,6 +1649,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -2006,6 +2022,7 @@ describe('actions/IOU/TrackExpense', () => { isSelfTourViewed: true, currentUserLocalCurrency: undefined, delegateAccountID: undefined, + formatPhoneNumber, }); // Then the result should contain valid track expense data @@ -2055,6 +2072,7 @@ describe('actions/IOU/TrackExpense', () => { isSelfTourViewed: false, currentUserLocalCurrency: undefined, delegateAccountID: undefined, + formatPhoneNumber, }); // Then the result should contain valid track expense data @@ -2106,6 +2124,7 @@ describe('actions/IOU/TrackExpense', () => { isSelfTourViewed: true, currentUserLocalCurrency: undefined, delegateAccountID: undefined, + formatPhoneNumber, }); // Then result should be valid @@ -2148,6 +2167,7 @@ describe('actions/IOU/TrackExpense', () => { isSelfTourViewed: false, currentUserLocalCurrency: undefined, delegateAccountID: undefined, + formatPhoneNumber, }); expect(resultWithoutTourViewed).toBeDefined(); @@ -2218,6 +2238,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: 'USD', delegateAccountID: undefined, isDraftChatReport: true, + formatPhoneNumber, }); // Then createdWorkspaceParams should be defined because the report is a draft @@ -2267,6 +2288,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: 'USD', delegateAccountID: undefined, isDraftChatReport: false, + formatPhoneNumber, }); // Then createdWorkspaceParams should be undefined because the report is not a draft @@ -2356,6 +2378,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -2663,6 +2686,7 @@ describe('actions/IOU/TrackExpense', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index 7188f77a1234..6caf6ca8b409 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -26,6 +26,7 @@ import createRandomTransaction from '../utils/collections/transaction'; import createMock from '../utils/createMock'; import getOnyxValue from '../utils/getOnyxValue'; import * as TestHelper from '../utils/TestHelper'; +import {formatPhoneNumber} from '../utils/TestHelper'; import { getOptionalNumberProperty, isGuidedSetupTask, @@ -7354,6 +7355,7 @@ describe('actions/Policy', () => { reportActionsList: {}, doesEmployeePersonalDetailExist: false, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -7395,6 +7397,7 @@ describe('actions/Policy', () => { reportActionsList: {}, doesEmployeePersonalDetailExist: false, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber, }); expect(result).toBeUndefined(); }); @@ -7453,6 +7456,7 @@ describe('actions/Policy', () => { reportActionsList, doesEmployeePersonalDetailExist: true, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber, }); // Verify the function returns a valid result (not undefined) @@ -7507,6 +7511,7 @@ describe('actions/Policy', () => { reportActionsList: {}, doesEmployeePersonalDetailExist: false, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -7577,6 +7582,7 @@ describe('actions/Policy', () => { reportActionsList: {}, doesEmployeePersonalDetailExist: false, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber, }); await waitForBatchedUpdates(); diff --git a/tests/ui/UnreadIndicatorsTest.tsx b/tests/ui/UnreadIndicatorsTest.tsx index 9c992d40d3c1..c3a2ca771d15 100644 --- a/tests/ui/UnreadIndicatorsTest.tsx +++ b/tests/ui/UnreadIndicatorsTest.tsx @@ -35,6 +35,7 @@ import type {NativeNavigationMock} from '../../__mocks__/@react-navigation/nativ import {createRandomReport} from '../utils/collections/reports'; import createRandomTransaction from '../utils/collections/transaction'; import PusherHelper from '../utils/PusherHelper'; +import {formatPhoneNumber} from '../utils/TestHelper'; import * as TestHelper from '../utils/TestHelper'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; @@ -812,6 +813,7 @@ describe('Unread Indicators', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); diff --git a/tests/unit/GoogleTagManagerTest.tsx b/tests/unit/GoogleTagManagerTest.tsx index 38d70c800e5d..1116c614eb9d 100644 --- a/tests/unit/GoogleTagManagerTest.tsx +++ b/tests/unit/GoogleTagManagerTest.tsx @@ -18,7 +18,7 @@ import {NavigationContainer} from '@react-navigation/native'; import Onyx from 'react-native-onyx'; import getOnyxValue from '../utils/getOnyxValue'; -import {getCurrencyDecimalsLocal} from '../utils/TestHelper'; +import {getCurrencyDecimalsLocal, formatPhoneNumber} from '../utils/TestHelper'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; jest.mock('@libs/GoogleTagManager'); @@ -300,6 +300,7 @@ describe('GoogleTagManagerTest', () => { currentUserLocalCurrency: undefined, delegateAccountID: undefined, reportActionsList: undefined, + formatPhoneNumber, }); await waitForBatchedUpdatesWithAct(); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 779e6f91da5f..d5c583303f5e 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -3358,13 +3358,13 @@ describe('ReportUtils', () => { }); it('should return the correct parent navigation subtitle for the archived invoice report', () => { - const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, undefined, true); + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, formatPhoneNumber, undefined, true); const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok (archived)'}); }); it('should return the correct parent navigation subtitle for the non archived invoice report', () => { - const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, undefined, false); + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, formatPhoneNumber, undefined, false); const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok'}); }); @@ -3383,7 +3383,7 @@ describe('ReportUtils', () => { role: CONST.POLICY.ROLE.ADMIN, }); - const actual = getParentNavigationSubtitle(expenseReport, testPolicy, undefined, translateLocal, undefined); + const actual = getParentNavigationSubtitle(expenseReport, testPolicy, undefined, translateLocal, formatPhoneNumber, undefined); expect(actual.workspaceName).toBe('Direct Policy Name'); }); @@ -3411,14 +3411,14 @@ describe('ReportUtils', () => { }; return Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}200`, parentInvoiceRoom).then(() => { - const actual = getParentNavigationSubtitle(invoiceReport, testPolicy, undefined, translateLocal, undefined); + const actual = getParentNavigationSubtitle(invoiceReport, testPolicy, undefined, translateLocal, formatPhoneNumber, undefined); const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; expect(normalizedActual.reportName).toContain('Invoice Policy'); }); }); it('should fall back to allPolicies when policy parameter is undefined', () => { - const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, undefined); + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, formatPhoneNumber, undefined); const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; // Should still resolve via Onyx-connected allPolicies or report.policyName expect(normalizedActual.reportName).toContain('A workspace'); @@ -3431,7 +3431,7 @@ describe('ReportUtils', () => { reportName: 'Chat Report', type: CONST.REPORT.TYPE.CHAT, }; - const actual = getParentNavigationSubtitle(chatReport, undefined, undefined, translateLocal, undefined); + const actual = getParentNavigationSubtitle(chatReport, undefined, undefined, translateLocal, formatPhoneNumber, undefined); expect(actual).toEqual({}); }); @@ -3458,13 +3458,13 @@ describe('ReportUtils', () => { }) .then(waitForBatchedUpdates) .then(() => { - const actual = getParentNavigationSubtitle(childReport, undefined, conciergeReportID, translateLocal, 'Concierge'); + const actual = getParentNavigationSubtitle(childReport, undefined, conciergeReportID, translateLocal, formatPhoneNumber, 'Concierge'); expect(actual.reportName).toBe('Concierge'); }); }); it('should return reportName and workspaceName when parent report exists and conciergeReportID is undefined', () => { - const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, undefined); + const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, undefined, undefined, translateLocal, formatPhoneNumber, undefined); expect(actual).toHaveProperty('reportName'); }); @@ -3476,7 +3476,7 @@ describe('ReportUtils', () => { const expenseReport = {reportID: '780051', type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: hiddenOwnerAccountID}; const translateWithHiddenMarker: LocalizedTranslate = (path, ...parameters) => (path === 'common.hidden' ? 'HiddenMarker' : translateLocal(path, ...parameters)); - const actual = getParentNavigationSubtitle(expenseReport, undefined, undefined, translateWithHiddenMarker, undefined); + const actual = getParentNavigationSubtitle(expenseReport, undefined, undefined, translateWithHiddenMarker, formatPhoneNumber, undefined); expect(actual.reportName).toContain('HiddenMarker'); }); }); @@ -3540,7 +3540,7 @@ describe('ReportUtils', () => { originalMessage: {amount: 1000, currency: CONST.CURRENCY.USD}, }); - const result = getReimbursementDeQueuedOrCanceledActionMessage(translateWithHiddenMarker, reportAction, hiddenAccountID, convertToDisplayString); + const result = getReimbursementDeQueuedOrCanceledActionMessage(translateWithHiddenMarker, formatPhoneNumber, reportAction, hiddenAccountID, convertToDisplayString); expect(result).toContain('HiddenMarker'); }); @@ -3553,7 +3553,7 @@ describe('ReportUtils', () => { originalMessage: {amount: 1000, currency: CONST.CURRENCY.USD, cancellationReason: CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN}, }); - const result = getReimbursementDeQueuedOrCanceledActionMessage(translateWithAdminMarker, reportAction, 780020, convertToDisplayString); + const result = getReimbursementDeQueuedOrCanceledActionMessage(translateWithAdminMarker, formatPhoneNumber, reportAction, 780020, convertToDisplayString); expect(result).toBe('AdminCanceledMarker'); }); }); @@ -5181,6 +5181,7 @@ describe('ReportUtils', () => { const reportPreview = buildOptimisticReportPreview( chatReport, expenseReport, + formatPhoneNumber, getCurrencyDecimalsLocal, '', expenseTransaction, @@ -12890,7 +12891,7 @@ describe('ReportUtils', () => { managerID: 2, }; - const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, getCurrencyDecimalsLocal); + const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, formatPhoneNumber, getCurrencyDecimalsLocal); expect(reportPreviewAction.childOwnerAccountID).toBe(iouReport.ownerAccountID); expect(reportPreviewAction.childManagerAccountID).toBe(iouReport.managerID); @@ -12912,10 +12913,11 @@ describe('ReportUtils', () => { managerID: 2, }; - const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, getCurrencyDecimalsLocal); + const reportPreviewAction = buildOptimisticReportPreview(chatReport, iouReport, formatPhoneNumber, getCurrencyDecimalsLocal); const updatedPreviewAction = updateReportPreview( iouReport, reportPreviewAction, + formatPhoneNumber, getCurrencyDecimalsLocal, false, '', @@ -16459,7 +16461,10 @@ describe('ReportUtils', () => { }; // When we call getReportPreviewReportActionMessage - const result = getReportPreviewReportActionMessage({reportOrID: report, iouReportAction: reportAction, originalReportAction: reportAction}, getCurrencyDecimalsLocal); + const result = getReportPreviewReportActionMessage( + {reportOrID: report, iouReportAction: reportAction, originalReportAction: reportAction, formatPhoneNumber}, + getCurrencyDecimalsLocal, + ); // Then it should return the childReportName instead of "payer owes $0" expect(result).toBe('Expense Report 2025-01-15'); @@ -16479,7 +16484,10 @@ describe('ReportUtils', () => { }; // When we call getReportPreviewReportActionMessage - const result = getReportPreviewReportActionMessage({reportOrID: report, iouReportAction: reportAction, originalReportAction: reportAction}, getCurrencyDecimalsLocal); + const result = getReportPreviewReportActionMessage( + {reportOrID: report, iouReportAction: reportAction, originalReportAction: reportAction, formatPhoneNumber}, + getCurrencyDecimalsLocal, + ); // Then it should return the message from the report action (not the childReportName) expect(result).toBe('payer owes $100'); @@ -16572,7 +16580,7 @@ describe('ReportUtils', () => { }; const result = getReportPreviewReportActionMessage( - {reportOrID: settledReport, iouReportAction: actionWithAccountNumber, originalReportAction: actionWithAccountNumber}, + {reportOrID: settledReport, iouReportAction: actionWithAccountNumber, originalReportAction: actionWithAccountNumber, formatPhoneNumber}, getCurrencyDecimalsLocal, ); @@ -16582,7 +16590,7 @@ describe('ReportUtils', () => { it('falls back to the policy default bank account when the action has no accountNumber', () => { const result = getReportPreviewReportActionMessage( - {reportOrID: settledReport, iouReportAction: payReportAction, originalReportAction: payReportAction}, + {reportOrID: settledReport, iouReportAction: payReportAction, originalReportAction: payReportAction, formatPhoneNumber}, getCurrencyDecimalsLocal, ); @@ -16591,10 +16599,12 @@ describe('ReportUtils', () => { it('matches the localized getReportPreviewMessage output when translated to English', () => { const englishTranslate: LocalizedTranslate = (path, ...parameters) => translate(CONST.LOCALES.EN, path, ...parameters); - const params = {reportOrID: settledReport, iouReportAction: payReportAction, originalReportAction: payReportAction}; + const params = {reportOrID: settledReport, iouReportAction: payReportAction, originalReportAction: payReportAction, formatPhoneNumber}; // The hardcoded English copy must not drift from the localized function - expect(getReportPreviewReportActionMessage(params, getCurrencyDecimalsLocal)).toBe(getReportPreviewMessage(englishTranslate, convertToDisplayString, params)); + expect(getReportPreviewReportActionMessage(params, getCurrencyDecimalsLocal)).toBe( + getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, params), + ); }); describe('cross-border payment', () => { @@ -16603,11 +16613,11 @@ describe('ReportUtils', () => { ...payReportAction, originalMessage: {...payOriginalMessage, creditedAmount: 1340, creditedCurrency: 'GBP', creditBankAccountLast4: '3335'}, }; - const crossBorderParams = {reportOrID: settledReport, iouReportAction: crossBorderAction, originalReportAction: crossBorderAction}; + const crossBorderParams = {reportOrID: settledReport, iouReportAction: crossBorderAction, originalReportAction: crossBorderAction, formatPhoneNumber}; it('names the credited amount, falling back to the policy default for the debited account', () => { // Given a converted payment that recorded the employee's account but not the account it was paid from - const result = getReportPreviewMessage(englishTranslate, convertToDisplayString, crossBorderParams); + const result = getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, crossBorderParams); // Then the debited account comes from the policy default, the same fallback the non-converted wording uses expect(result).toBe( @@ -16622,22 +16632,23 @@ describe('ReportUtils', () => { it('stores the same wording on the report action as the localized preview shows', () => { // The hardcoded English copy must not drift from the localized function expect(getReportPreviewReportActionMessage(crossBorderParams, getCurrencyDecimalsLocal)).toBe( - getReportPreviewMessage(englishTranslate, convertToDisplayString, crossBorderParams), + getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, crossBorderParams), ); }); it('still names the report total in the parent chat preview', () => { // Given the parent chat preview, which summarizes the report rather than describing the payment const params = {...crossBorderParams, isPreviewMessageForParentChatReport: true}; - const paymentWithoutConversion = getReportPreviewMessage(englishTranslate, convertToDisplayString, { + const paymentWithoutConversion = getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, { reportOrID: settledReport, iouReportAction: payReportAction, originalReportAction: payReportAction, isPreviewMessageForParentChatReport: true, + formatPhoneNumber, }); // Then the credited amount does not replace the report total, which is what the report is denominated in - expect(getReportPreviewMessage(englishTranslate, convertToDisplayString, params)).toBe(paymentWithoutConversion); + expect(getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, params)).toBe(paymentWithoutConversion); }); }); }); @@ -16657,14 +16668,16 @@ describe('ReportUtils', () => { }); it('uses the injected translate function (not translateLocal) so output follows the passed locale, while getReportPreviewReportActionMessage stays English', async () => { - const params = {reportOrID: expenseReport}; + const params = {reportOrID: expenseReport, formatPhoneNumber}; const englishTranslate: LocalizedTranslate = (path, ...parameters) => translate(CONST.LOCALES.EN, path, ...parameters); const spanishTranslate: LocalizedTranslate = (path, ...parameters) => translate(CONST.LOCALES.ES, path, ...parameters); await IntlStore.load(CONST.LOCALES.ES).then(waitForBatchedUpdates); // The localized preview differs between English and Spanish... - expect(getReportPreviewMessage(spanishTranslate, convertToDisplayString, params)).not.toBe(getReportPreviewMessage(englishTranslate, convertToDisplayString, params)); + expect(getReportPreviewMessage(spanishTranslate, formatPhoneNumber, convertToDisplayString, params)).not.toBe( + getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, params), + ); // ...but the report-action-message variant is always the English text, regardless of the loaded locale // TODO: Re-enable this assertion once getReportPreviewReportActionMessage is refactored @@ -16694,7 +16707,7 @@ describe('ReportUtils', () => { const translateWithMarker: LocalizedTranslate = (path, ...parameters) => path === 'common.hidden' ? 'HiddenParticipantMarker' : translate(CONST.LOCALES.EN, path, ...parameters); - const result = getReportPreviewMessage(translateWithMarker, convertToDisplayString, {reportOrID: iouReport}); + const result = getReportPreviewMessage(translateWithMarker, formatPhoneNumber, convertToDisplayString, {reportOrID: iouReport, formatPhoneNumber}); // The manager's name resolves to the marker, proving getDisplayNameForParticipant received the injected translate expect(result).toContain('HiddenParticipantMarker'); @@ -16714,10 +16727,10 @@ describe('ReportUtils', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); const englishTranslate: LocalizedTranslate = (path, ...parameters) => translate(CONST.LOCALES.EN, path, ...parameters); - const result = getReportPreviewReportActionMessage({reportOrID: report}, getCurrencyDecimalsLocal); + const result = getReportPreviewReportActionMessage({reportOrID: report, formatPhoneNumber}, getCurrencyDecimalsLocal); // The hardcoded English string must match the en.ts translation produced by the localized function - expect(result).toBe(getReportPreviewMessage(englishTranslate, convertToDisplayString, {reportOrID: report})); + expect(result).toBe(getReportPreviewMessage(englishTranslate, formatPhoneNumber, convertToDisplayString, {reportOrID: report, formatPhoneNumber})); expect(result).toContain('owes'); }); }); @@ -16763,7 +16776,7 @@ describe('ReportUtils', () => { const translateWithMarker: LocalizedTranslate = (path, ...parameters) => (path === 'common.hidden' ? 'HiddenPayeeMarker' : translate(CONST.LOCALES.EN, path, ...parameters)); // The nameless payee resolves to the marker, proving getDisplayNameForParticipant received the injected translate - expect(getPayeeName(report, translateWithMarker)).toBe('HiddenPayeeMarker'); + expect(getPayeeName(report, translateWithMarker, formatPhoneNumber)).toBe('HiddenPayeeMarker'); }); }); @@ -20625,7 +20638,7 @@ describe('ReportUtils', () => { }; // REPORT_PREVIEW action that sits in the chat report and links to the expense report - const reportPreviewAction = buildOptimisticReportPreview(chatReport, expenseReport, getCurrencyDecimalsLocal, '', transaction); + const reportPreviewAction = buildOptimisticReportPreview(chatReport, expenseReport, formatPhoneNumber, getCurrencyDecimalsLocal, '', transaction); beforeAll(async () => { await Onyx.set(ONYXKEYS.SESSION, {email: currentUserEmail, accountID: currentUserAccountID}); From 18abcd635495bb82b9cb18de4b80cb47b8b80b6f Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 00:18:04 +0430 Subject: [PATCH 04/19] Pass formatPhoneNumber through approval and payment flows --- .../useConfirmApproval.ts | 3 +++ .../useConfirmApproveReportAction.ts | 3 +++ .../SearchList/ListItem/ExpenseReportListItem.tsx | 3 ++- .../SearchList/ListItem/ReportListItemHeader.tsx | 3 ++- .../ListItem/TransactionListItem/index.tsx | 3 ++- src/components/SettlementButton/index.tsx | 3 ++- src/hooks/useHoldMenuSubmit.ts | 1 + src/hooks/useLifecycleActions.tsx | 1 + src/hooks/useSearchBulkActions.ts | 1 + src/libs/PaymentUtils.ts | 5 ++++- src/pages/DynamicReportChangeWorkspacePage.tsx | 4 +++- tests/actions/IOU/RequestMoneyTest.ts | 1 - tests/actions/IOUTest/ReportWorkflowTest.ts | 12 ++++++++++++ tests/actions/TransactionTest.ts | 3 ++- tests/unit/Search/handleActionButtonPressTest.ts | 5 ++++- 15 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts b/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts index 7efbb5184e10..9671ae9afc49 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts +++ b/src/components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts @@ -4,6 +4,7 @@ import {useMoneyReportHeaderModals} from '@components/MoneyReportHeaderModalsCon import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDelegateAccountID from '@hooks/useDelegateAccountID'; +import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; import useTransactionsAndViolationsForReport from '@hooks/useTransactionsAndViolationsForReport'; @@ -25,6 +26,7 @@ function useConfirmApproval(reportID: string | undefined, startApprovedAnimation const {accountID, email} = useCurrentUserPersonalDetails(); const {getCurrencyDecimals} = useCurrencyListActions(); const {isBetaEnabled} = usePermissions(); + const {formatPhoneNumber} = useLocalize(); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); const {openHoldMenu} = useMoneyReportHeaderModals(); @@ -76,6 +78,7 @@ function useConfirmApproval(reportID: string | undefined, startApprovedAnimation delegateEmail, delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } }; diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/useConfirmApproveReportAction.ts b/src/components/ReportActionItem/MoneyRequestReportPreview/useConfirmApproveReportAction.ts index 7ed2e561bbb1..8e4edc00cffc 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/useConfirmApproveReportAction.ts +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/useConfirmApproveReportAction.ts @@ -6,6 +6,7 @@ import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/ import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; @@ -26,6 +27,7 @@ import {useReportPreviewActions, useReportPreviewActionState} from './MoneyReque function useConfirmApproveReportAction(actionButtonData: ReturnType, transactions: Transaction[], hasViolations: boolean) { const currentUserDetails = useCurrentUserPersonalDetails(); const {getCurrencyDecimals} = useCurrencyListActions(); + const {formatPhoneNumber} = useLocalize(); const {isBetaEnabled} = usePermissions(); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); @@ -60,6 +62,7 @@ function useConfirmApproveReportAction(actionButtonData: ReturnType({ const areAllReportTransactionsSelected = transactionsWithoutPendingDelete.length > 0 && transactionsWithoutPendingDelete.every((transaction) => selectedTransactions[transaction.keyForList]?.isSelected); const isSelected = liveRowSelected || areAllReportTransactionsSelected; - const {translate, dateFnsLocale} = useLocalize(); + const {translate, dateFnsLocale, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals, convertToDisplayString} = useCurrencyListActions(); const {isLargeScreenWidth} = useResponsiveLayout(); const {currentSearchHash, currentSearchKey} = useSearchQueryContext(); @@ -305,6 +305,7 @@ function ExpenseReportListItemInner({ delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); }, [ currentSearchHash, diff --git a/src/components/Search/SearchList/ListItem/ReportListItemHeader.tsx b/src/components/Search/SearchList/ListItem/ReportListItemHeader.tsx index 8912b377b525..02b970df83d9 100644 --- a/src/components/Search/SearchList/ListItem/ReportListItemHeader.tsx +++ b/src/components/Search/SearchList/ListItem/ReportListItemHeader.tsx @@ -288,7 +288,7 @@ function ReportListItemHeaderInner({ }); const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {showConfirmModal} = useConfirmModal(); const {isSelected} = useRowSelection(reportItem.keyForList); @@ -334,6 +334,7 @@ function ReportListItemHeaderInner({ delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); }; return !isLargeScreenWidth ? ( diff --git a/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx b/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx index f7c793f0b5cb..8b08c34f38ea 100644 --- a/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx +++ b/src/components/Search/SearchList/ListItem/TransactionListItem/index.tsx @@ -198,7 +198,7 @@ function TransactionListItemInner({ const {isDelegateAccessRestricted} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {showConfirmModal} = useConfirmModal(); const openReportSubmitToPopover = useOpenReportSubmitToPopover(); @@ -241,6 +241,7 @@ function TransactionListItemInner({ delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, }); }; diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index 8b3486942da4..95055edb4046 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -115,7 +115,7 @@ function SettlementButton({ }: SettlementButtonProps) { const icons = useMemoizedLazyExpensifyIcons(['CheckCircle', 'ThumbsUp', 'Bank', 'Cash', 'Wallet', 'Building', 'User']); const styles = useThemeStyles(); - const {translate, localeCompare} = useLocalize(); + const {translate, localeCompare, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {isOffline} = useNetwork(); const policy = usePolicy(policyID); @@ -524,6 +524,7 @@ function SettlementButton({ delegateEmail, delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } return; diff --git a/src/hooks/useHoldMenuSubmit.ts b/src/hooks/useHoldMenuSubmit.ts index fa5c47711f6c..c0364854f7d3 100644 --- a/src/hooks/useHoldMenuSubmit.ts +++ b/src/hooks/useHoldMenuSubmit.ts @@ -104,6 +104,7 @@ function useHoldMenuSubmit({moneyRequestReport, chatReport, requestType, payment delegateEmail, delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); } else if (currentChatReport && paymentType) { payMoneyRequest({ diff --git a/src/hooks/useLifecycleActions.tsx b/src/hooks/useLifecycleActions.tsx index a9290acff605..80c7df76dfb2 100644 --- a/src/hooks/useLifecycleActions.tsx +++ b/src/hooks/useLifecycleActions.tsx @@ -198,6 +198,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, delegateEmail, delegateAccountID, isTrackIntentUser, + formatPhoneNumber, }); if (skipAnimation) { clearSelectedTransactions(true); diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index 58219c56d6f6..1b78babbf9fc 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -1045,6 +1045,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { additionalOnyxData: getSearchApproveOnyxData(hash, reportID, currentSearchKey), shouldPlaySuccessSound: false, isTrackIntentUser, + formatPhoneNumber, }); if (!wouldNavigateToUpgrade && !wouldNavigateToRestricted) { diff --git a/src/libs/PaymentUtils.ts b/src/libs/PaymentUtils.ts index 0aba0848554b..7269609363c4 100644 --- a/src/libs/PaymentUtils.ts +++ b/src/libs/PaymentUtils.ts @@ -1,7 +1,7 @@ import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; import getBankIcon from '@components/Icon/BankIcons'; import type {ContinueActionParams} from '@components/KYCWall/types'; -import type {LocalizedTranslate} from '@components/LocaleContextProvider'; +import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import type {BankAccountMenuItem} from '@components/Search/types'; import type {PaymentActionParams} from '@components/SettlementButton/types'; @@ -58,6 +58,7 @@ type SelectPaymentTypeParams = { isTrackIntentUser: boolean | undefined; ownerLogin: string | undefined; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; type BusinessBankAccountOption = { @@ -234,6 +235,7 @@ const selectPaymentType = (params: SelectPaymentTypeParams) => { isTrackIntentUser, ownerLogin, getCurrencyDecimals, + formatPhoneNumber, } = params; if (policy && shouldRestrictUserBillableActions(policy, ownerBillingGracePeriodEnd, userBillingGracePeriodEnds, amountOwed, currentAccountID)) { Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(policy.id)); @@ -271,6 +273,7 @@ const selectPaymentType = (params: SelectPaymentTypeParams) => { delegateAccountID, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }); } return; diff --git a/src/pages/DynamicReportChangeWorkspacePage.tsx b/src/pages/DynamicReportChangeWorkspacePage.tsx index a9666643729a..dbd5c4b7273a 100644 --- a/src/pages/DynamicReportChangeWorkspacePage.tsx +++ b/src/pages/DynamicReportChangeWorkspacePage.tsx @@ -70,7 +70,7 @@ function DynamicReportChangeWorkspacePage({report}: DynamicReportChangeWorkspace const {isOffline} = useNetwork(); const styles = useThemeStyles(); const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); - const {translate, localeCompare} = useLocalize(); + const {translate, localeCompare, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const reportTransactions = useReportTransactions(reportID); @@ -168,6 +168,7 @@ function DynamicReportChangeWorkspacePage({report}: DynamicReportChangeWorkspace reportPreviewAction, isTrackIntentUser, reportTransactions, + formatPhoneNumber, }); return; } @@ -188,6 +189,7 @@ function DynamicReportChangeWorkspacePage({report}: DynamicReportChangeWorkspace reportPreviewAction, isTrackIntentUser, reportTransactions, + formatPhoneNumber, }); }; diff --git a/tests/actions/IOU/RequestMoneyTest.ts b/tests/actions/IOU/RequestMoneyTest.ts index b07b6967252b..aedce60190f3 100644 --- a/tests/actions/IOU/RequestMoneyTest.ts +++ b/tests/actions/IOU/RequestMoneyTest.ts @@ -3175,7 +3175,6 @@ describe('actions/IOU', () => { isTrackIntentUser: false, formatPhoneNumber, delegateAccountID: undefined, - formatPhoneNumber, }; }; diff --git a/tests/actions/IOUTest/ReportWorkflowTest.ts b/tests/actions/IOUTest/ReportWorkflowTest.ts index eddaa8527b66..5bf762d834b4 100644 --- a/tests/actions/IOUTest/ReportWorkflowTest.ts +++ b/tests/actions/IOUTest/ReportWorkflowTest.ts @@ -2444,6 +2444,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure @@ -2487,6 +2488,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure @@ -3209,6 +3211,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, ownerLogin: undefined, + formatPhoneNumber, }); beforeEach(() => { @@ -3398,6 +3401,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3452,6 +3456,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3505,6 +3510,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3633,6 +3639,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3666,6 +3673,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3697,6 +3705,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3758,6 +3767,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -3819,6 +3829,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); return waitForBatchedUpdates(); }) @@ -3952,6 +3963,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); await waitForBatchedUpdates(); diff --git a/tests/actions/TransactionTest.ts b/tests/actions/TransactionTest.ts index 9e15f0bc4466..15425e36b62a 100644 --- a/tests/actions/TransactionTest.ts +++ b/tests/actions/TransactionTest.ts @@ -215,7 +215,7 @@ describe('actions/Transaction', () => { await waitForBatchedUpdates(); - createNewReport(creatorPersonalDetails, true, false, mockPolicy, [CONST.BETAS.ALL], false, getCurrencyDecimalsLocal); + createNewReport(creatorPersonalDetails, true, false, mockPolicy, [CONST.BETAS.ALL], false, getCurrencyDecimalsLocal, formatPhoneNumber); // Create a tracked expense const selfDMReport: Report = { ...createRandomReport(1, CONST.REPORT.CHAT_TYPE.SELF_DM), @@ -256,6 +256,7 @@ describe('actions/Transaction', () => { delegateAccountID: undefined, reportActionsList: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); await getOnyxData({ key: ONYXKEYS.COLLECTION.TRANSACTION, diff --git a/tests/unit/Search/handleActionButtonPressTest.ts b/tests/unit/Search/handleActionButtonPressTest.ts index c168bfa7eb16..46d19a0bf482 100644 --- a/tests/unit/Search/handleActionButtonPressTest.ts +++ b/tests/unit/Search/handleActionButtonPressTest.ts @@ -14,7 +14,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import createRandomPolicy from '../../utils/collections/policies'; -import {getCurrencyDecimalsLocal} from '../../utils/TestHelper'; +import {getCurrencyDecimalsLocal, formatPhoneNumber} from '../../utils/TestHelper'; jest.mock('@src/components/ConfirmedRoute.tsx'); jest.mock('@libs/deferModalPresentationAfterPopoverDismiss', () => ({ @@ -359,6 +359,7 @@ describe('handleActionButtonPress', () => { currentUserAccountID: 1206, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); expect(goToItem).not.toHaveBeenCalled(); }); @@ -385,6 +386,7 @@ describe('handleActionButtonPress', () => { currentUserAccountID: 1206, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); expect(onHoldMenuOpen).toHaveBeenCalledWith(mockReportItemWithHold, CONST.IOU.REPORT_ACTION_TYPE.APPROVE); @@ -411,6 +413,7 @@ describe('handleActionButtonPress', () => { currentUserAccountID: 1206, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); expect(goToItem).toHaveBeenCalledTimes(0); }); From 0d72a8dd678bbb7d1732bf10bf0e8ced7cf9b1c8 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 00:41:41 +0430 Subject: [PATCH 05/19] Pass phone formatter through payment and report flows --- .../MoneyReportHeaderSecondaryActions.tsx | 1 + src/hooks/useSelectionModePayment.ts | 1 + tests/actions/ReportTest.ts | 68 ++++++++++++++++--- tests/actions/TransactionTest.ts | 2 +- tests/unit/PaymentUtilsTest.ts | 3 +- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx index f287ea994f8c..51dd11315360 100644 --- a/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx +++ b/src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx @@ -435,6 +435,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo const runPaymentSelection = () => selectPaymentType({ getCurrencyDecimals, + formatPhoneNumber, event, iouPaymentType, triggerKYCFlow, diff --git a/src/hooks/useSelectionModePayment.ts b/src/hooks/useSelectionModePayment.ts index ba154bfa9558..c97be4eb2cbe 100644 --- a/src/hooks/useSelectionModePayment.ts +++ b/src/hooks/useSelectionModePayment.ts @@ -306,6 +306,7 @@ function useSelectionModePayment({ const invokePaymentSelect = (event: KYCFlowEvent, iouPaymentType: PaymentMethodType, triggerKYCFlow: TriggerKYCFlow) => { selectPaymentType({ getCurrencyDecimals, + formatPhoneNumber, event, iouPaymentType, triggerKYCFlow, diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index ecd04062b6e4..dd1a4012974c 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2791,7 +2791,7 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); mockFetchData.pause(); - const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal); + const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); const reportPreviewAction = await new Promise>>((resolve) => { @@ -2857,7 +2857,9 @@ describe('actions/Report', () => { type: CONST.POLICY.TYPE.TEAM, }; - Report.createNewReport({accountID: 1234}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, undefined, {managedCardTransactionID}); + Report.createNewReport({accountID: 1234}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber, undefined, { + managedCardTransactionID, + }); expect(apiWriteSpy).toHaveBeenCalledWith(WRITE_COMMANDS.CREATE_APP_REPORT, expect.objectContaining({managedCardTransactionID}), expect.anything()); }); @@ -2878,7 +2880,7 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); mockFetchData.pause(); - Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal); + Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); await new Promise((resolve) => { @@ -2916,7 +2918,7 @@ describe('actions/Report', () => { } // When create new report - Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal); + Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); // Then the parent report's hasOutstandingChildRequest property should remain unchanged await new Promise((resolve) => { @@ -2951,7 +2953,17 @@ describe('actions/Report', () => { } // When create new report - const optimisticReportData = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal); + const optimisticReportData = Report.createNewReport( + {accountID}, + true, + false, + policy, + [CONST.BETAS.ALL], + false, + TestHelper.getCurrencyDecimalsLocal, + false, + TestHelper.formatPhoneNumber, + ); await waitForBatchedUpdates(); // Then the report's status should be draft. @@ -2993,7 +3005,7 @@ describe('actions/Report', () => { }; await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); - const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal); + const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); await waitForBatchedUpdates(); @@ -3583,6 +3595,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: targetPolicy, currentUserAccountID: 1, @@ -3619,6 +3632,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: newPolicy, currentUserAccountID: 1, @@ -3681,6 +3695,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport, policy: newPolicy, currentUserAccountID: 1, @@ -3753,6 +3768,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: newPolicy, currentUserAccountID: 1, @@ -3851,6 +3867,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: newPolicy, currentUserAccountID: 1, @@ -3937,6 +3954,7 @@ describe('actions/Report', () => { Report.changeReportPolicy({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: newPolicy, currentUserAccountID: 1, @@ -3991,6 +4009,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: createRandomPolicy(Number(2)), currentUser: {accountID: 1}, @@ -4084,6 +4103,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: newPolicy, currentUser: {accountID: 1}, @@ -4130,6 +4150,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: createRandomPolicy(Number(2)), currentUser: {accountID: 1}, @@ -4162,6 +4183,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: targetPolicy, currentUser: {accountID: 1}, @@ -4193,6 +4215,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: createRandomPolicy(Number(2)), currentUser: {accountID: 1}, @@ -4224,6 +4247,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: createRandomPolicy(Number(2)), currentUser: {accountID: 1}, @@ -4257,6 +4281,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: createRandomPolicy(Number(2)), currentUser: {accountID: 1}, @@ -4311,6 +4336,7 @@ describe('actions/Report', () => { Report.changeReportPolicyAndInviteSubmitter({ report: expenseReport, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy: targetPolicy, currentUser: {accountID: 1, email: 'current-user@expensifail.com'}, @@ -4760,6 +4786,7 @@ describe('actions/Report', () => { Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy, currentUserAccountID: 1, @@ -4815,6 +4842,7 @@ describe('actions/Report', () => { const {optimisticData, successData, failureData} = Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy, currentUserAccountID: 1, @@ -4880,6 +4908,7 @@ describe('actions/Report', () => { const {optimisticData} = Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy, currentUserAccountID: 1, @@ -4929,6 +4958,7 @@ describe('actions/Report', () => { const {optimisticData} = Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy, currentUserAccountID: 1, @@ -4991,6 +5021,7 @@ describe('actions/Report', () => { const {optimisticData} = Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport: undefined, policy, currentUserAccountID: 1, @@ -5056,6 +5087,7 @@ describe('actions/Report', () => { const {optimisticData, failureData} = Report.buildOptimisticChangePolicyData({ report, getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + formatPhoneNumber: TestHelper.formatPhoneNumber, parentReport, policy, currentUserAccountID: 1, @@ -9548,14 +9580,34 @@ describe('actions/Report', () => { it('sets delegateAccountID when delegateAccountIDParam is provided', () => { const chatReport = createMock({reportID: 'chat1'}); const iouReport = createMock({reportID: 'iou1', ownerAccountID: 1, managerID: 2}); - const result = ReportUtils.buildOptimisticReportPreview(chatReport, iouReport, TestHelper.getCurrencyDecimalsLocal, '', null, undefined, undefined, DELEGATE_ACCOUNT_ID); + const result = ReportUtils.buildOptimisticReportPreview( + chatReport, + iouReport, + TestHelper.formatPhoneNumber, + TestHelper.getCurrencyDecimalsLocal, + '', + null, + undefined, + undefined, + DELEGATE_ACCOUNT_ID, + ); expect(result.delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); }); it('does not set delegateAccountID when delegateAccountIDParam is undefined', () => { const chatReport = createMock({reportID: 'chat2'}); const iouReport = createMock({reportID: 'iou2', ownerAccountID: 1, managerID: 2}); - const result = ReportUtils.buildOptimisticReportPreview(chatReport, iouReport, TestHelper.getCurrencyDecimalsLocal, '', null, undefined, undefined, undefined); + const result = ReportUtils.buildOptimisticReportPreview( + chatReport, + iouReport, + TestHelper.formatPhoneNumber, + TestHelper.getCurrencyDecimalsLocal, + '', + null, + undefined, + undefined, + undefined, + ); expect(result.delegateAccountID).toBeUndefined(); }); }); diff --git a/tests/actions/TransactionTest.ts b/tests/actions/TransactionTest.ts index 15425e36b62a..f5bc73daf957 100644 --- a/tests/actions/TransactionTest.ts +++ b/tests/actions/TransactionTest.ts @@ -215,7 +215,7 @@ describe('actions/Transaction', () => { await waitForBatchedUpdates(); - createNewReport(creatorPersonalDetails, true, false, mockPolicy, [CONST.BETAS.ALL], false, getCurrencyDecimalsLocal, formatPhoneNumber); + createNewReport(creatorPersonalDetails, true, false, mockPolicy, [CONST.BETAS.ALL], false, getCurrencyDecimalsLocal, false, formatPhoneNumber); // Create a tracked expense const selfDMReport: Report = { ...createRandomReport(1, CONST.REPORT.CHAT_TYPE.SELF_DM), diff --git a/tests/unit/PaymentUtilsTest.ts b/tests/unit/PaymentUtilsTest.ts index 1582eae3eaf4..7646632709f5 100644 --- a/tests/unit/PaymentUtilsTest.ts +++ b/tests/unit/PaymentUtilsTest.ts @@ -15,7 +15,7 @@ import type PaymentMethod from '@src/types/onyx/PaymentMethod'; import createMockPaymentMethod from '../utils/collections/paymentMethods'; import createRandomPolicy from '../utils/collections/policies'; -import {getCurrencyDecimalsLocal} from '../utils/TestHelper'; +import {formatPhoneNumber, getCurrencyDecimalsLocal} from '../utils/TestHelper'; jest.mock('@libs/Navigation/Navigation', () => ({ navigate: jest.fn(), @@ -155,6 +155,7 @@ describe('PaymentUtils', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }; beforeEach(() => { From 972b9c98e2c18120b097b3273685e35d8cbde59e Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 14:02:15 +0430 Subject: [PATCH 06/19] Fix typecheck for search reject and upgrade report helpers --- src/pages/Search/SearchRejectReasonPage.tsx | 16 +++++++++------- .../iou/request/step/IOURequestStepUpgrade.tsx | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/pages/Search/SearchRejectReasonPage.tsx b/src/pages/Search/SearchRejectReasonPage.tsx index cc97433922a3..ecdca9490217 100644 --- a/src/pages/Search/SearchRejectReasonPage.tsx +++ b/src/pages/Search/SearchRejectReasonPage.tsx @@ -36,7 +36,7 @@ function SearchRejectReasonPage({route}: SearchRejectReasonPageProps) { const {reportID} = route.params ?? {}; const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const [betas] = useOnyx(ONYXKEYS.BETAS); @@ -62,18 +62,19 @@ function SearchRejectReasonPage({route}: SearchRejectReasonPageProps) { return; } - const urlToNavigateBack = rejectMoneyRequestsOnSearch( - currentSearchHash, - selectedTransactionsForReject, + const urlToNavigateBack = rejectMoneyRequestsOnSearch({ + hash: currentSearchHash, + selectedTransactions: selectedTransactionsForReject, comment, allPolicies, allReports, - currentUserAccountID, - currentUserLogin ?? '', + currentUserAccountIDParam: currentUserAccountID, + currentUserLogin: currentUserLogin ?? '', betas, delegateAccountID, getCurrencyDecimals, - ); + formatPhoneNumber, + }); if (route.name === SCREENS.SEARCH.MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS) { clearSelectedTransactions(true); } else { @@ -95,6 +96,7 @@ function SearchRejectReasonPage({route}: SearchRejectReasonPageProps) { betas, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, route.name, showDelegateNoAccessModal, clearSelectedTransactions, diff --git a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx index 1ff814cdbd7a..72761251f380 100644 --- a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx +++ b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx @@ -62,7 +62,7 @@ function IOURequestStepUpgrade({ }: IOURequestStepUpgradeProps) { const styles = useThemeStyles(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {isOffline} = useNetwork(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const delegateAccountID = useDelegateAccountID(); @@ -142,7 +142,17 @@ function IOURequestStepUpgrade({ if (upgradePath === CONST.UPGRADE_PATHS.REPORTS && policyID && selectedTransactionsKeys.includes(transactionID)) { const newPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; - const optimisticReport = createNewReport(ownerPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, newPolicy, betas, isTrackIntentUser, getCurrencyDecimals); + const optimisticReport = createNewReport( + ownerPersonalDetails, + hasViolations, + isASAPSubmitBetaEnabled, + newPolicy, + betas, + isTrackIntentUser, + getCurrencyDecimals, + false, + formatPhoneNumber, + ); const policyTagList = policyID ? allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] : {}; const reportsForCall = { From 37c9969b6cb5fac0e5df81c3e239e27462370c7f Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 14:37:21 +0430 Subject: [PATCH 07/19] Fix test mocks for formatPhoneNumber support --- src/hooks/useCreateNewReport.tsx | 2 +- tests/ui/ReportActionComposeTest.tsx | 1 + tests/ui/ReportActionMessageEditLayoutTest.tsx | 1 + tests/unit/PaymentUtilsTest.ts | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hooks/useCreateNewReport.tsx b/src/hooks/useCreateNewReport.tsx index dbfe51b706f2..25f683454be4 100644 --- a/src/hooks/useCreateNewReport.tsx +++ b/src/hooks/useCreateNewReport.tsx @@ -49,7 +49,7 @@ function useCreateNewReport() { shouldDismissEmptyReportsConfirmation, ); }, - [betas, currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policies, isTrackIntentUser, getCurrencyDecimals], + [betas, currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policies, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber], ); } diff --git a/tests/ui/ReportActionComposeTest.tsx b/tests/ui/ReportActionComposeTest.tsx index 465424818175..0801df7de48c 100644 --- a/tests/ui/ReportActionComposeTest.tsx +++ b/tests/ui/ReportActionComposeTest.tsx @@ -40,6 +40,7 @@ jest.mock('@hooks/useLocalize', () => jest.fn(() => ({ translate: jest.fn((key: string) => key), numberFormat: jest.fn((num: number) => num.toString()), + formatPhoneNumber: jest.fn((phone: string) => phone), })), ); diff --git a/tests/ui/ReportActionMessageEditLayoutTest.tsx b/tests/ui/ReportActionMessageEditLayoutTest.tsx index 7eace8954375..d678cb5106da 100644 --- a/tests/ui/ReportActionMessageEditLayoutTest.tsx +++ b/tests/ui/ReportActionMessageEditLayoutTest.tsx @@ -74,6 +74,7 @@ jest.mock('@hooks/useLocalize', () => jest.fn(() => ({ translate: jest.fn((key: string) => key), numberFormat: jest.fn((num: number) => num.toString()), + formatPhoneNumber: jest.fn((phone: string) => phone), })), ); diff --git a/tests/unit/PaymentUtilsTest.ts b/tests/unit/PaymentUtilsTest.ts index 7646632709f5..06dae15073d5 100644 --- a/tests/unit/PaymentUtilsTest.ts +++ b/tests/unit/PaymentUtilsTest.ts @@ -260,6 +260,7 @@ describe('PaymentUtils', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); }); @@ -290,6 +291,7 @@ describe('PaymentUtils', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); }); From fa018734b8d99a1a019794a9351da6629c76e648 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 15:24:26 +0430 Subject: [PATCH 08/19] fixed lint failure --- src/components/KYCWall/BaseKYCWall.tsx | 1 + .../ListItem/ExpenseReportListItem.tsx | 1 + src/hooks/useSearchBulkActions.ts | 1 + src/libs/actions/IOU/RejectMoneyRequest.ts | 38 ++++++++++++------- src/libs/actions/Report/index.ts | 36 ++++++++++++------ 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 1ab89fd47d48..5c21328c7cf7 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -291,6 +291,7 @@ function KYCWall({ conciergeChat, localCurrency, getCurrencyDecimals, + formatPhoneNumber, ], ); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx index a73a10c559c4..32a3f80b547a 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx @@ -348,6 +348,7 @@ function ExpenseReportListItemInner({ delegateAccountID, isTrackIntentUser, conciergeChat, + formatPhoneNumber, ]); const handleSelectionButtonPress = useCallback(() => { diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index 1b78babbf9fc..8a4b2b1dacfe 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -1086,6 +1086,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { personalDetails, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, ]); const {expenseCount, uniqueReportCount} = useMemo(() => { diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index 975cb831678f..854cf9930336 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -945,19 +945,31 @@ function prepareRejectMoneyRequestData({ return {optimisticData, successData, failureData, parameters, urlToNavigateBack: urlToNavigateBack as Route}; } -function rejectMoneyRequest( - transactionID: string, - reportID: string, - comment: string, - policy: OnyxEntry, - currentUserAccountIDParam: number, - currentUserLogin: string, - betas: OnyxEntry, - delegateAccountID: number | undefined, - formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], - options?: RejectMoneyRequestOptions, -): Route | undefined { +function rejectMoneyRequest({ + transactionID, + reportID, + comment, + policy, + currentUserAccountIDParam, + currentUserLogin, + betas, + delegateAccountID, + formatPhoneNumber, + getCurrencyDecimals, + options, +}: { + transactionID: string; + reportID: string; + comment: string; + policy: OnyxEntry; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + options?: RejectMoneyRequestOptions; +}): Route | undefined { const data = prepareRejectMoneyRequestData({ transactionID, reportID, diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index ff5e1f83703b..39ba57e363d3 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4395,19 +4395,31 @@ function buildNewReportOptimisticData({ }; } -function createNewReport( - ownerPersonalDetails: CurrentUserPersonalDetails, - hasViolationsParam: boolean, - isASAPSubmitBetaEnabled: boolean, - policy: OnyxEntry, - betas: OnyxEntry, - isTrackIntentUser: boolean | undefined, - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals'], +function createNewReport({ + ownerPersonalDetails, + hasViolationsParam, + isASAPSubmitBetaEnabled, + policy, + betas, + isTrackIntentUser, + getCurrencyDecimals, shouldNotifyNewAction = false, - formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], - shouldDismissEmptyReportsConfirmation?: boolean, - options: {managedCardTransactionID?: string; reportName?: string} = {}, -) { + formatPhoneNumber, + shouldDismissEmptyReportsConfirmation, + options = {}, +}: { + ownerPersonalDetails: CurrentUserPersonalDetails; + hasViolationsParam: boolean; + isASAPSubmitBetaEnabled: boolean; + policy: OnyxEntry; + betas: OnyxEntry; + isTrackIntentUser: boolean | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + shouldNotifyNewAction: boolean; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + shouldDismissEmptyReportsConfirmation?: boolean; + options: {managedCardTransactionID?: string; reportName?: string}; +}) { const {managedCardTransactionID, reportName} = options; const optimisticReportID = generateReportID(); const reportActionID = rand64(); From 0dff62fad9a22a7aeb978b2c4153f7aaf0c27617 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 17:03:51 +0430 Subject: [PATCH 09/19] Fix createNewReport and rejectMoneyRequest type signatures --- .../QuickCreationActionsBar/index.tsx | 15 +-- .../SearchActionsBarCreateButton.tsx | 15 +-- src/hooks/useCreateNewReport.tsx | 11 ++- src/libs/actions/IOU/Duplicate.ts | 13 ++- src/libs/actions/Search.ts | 20 +++- src/pages/Search/EmptySearchView.tsx | 13 +-- .../Search/SearchTransactionsChangeReport.tsx | 14 +-- .../AttachmentPickerWithMenuItems.tsx | 25 +++-- .../menuItems/CreateReportMenuItem.tsx | 15 +-- src/pages/iou/RejectReasonPage.tsx | 10 +- .../step/DynamicIOURequestEditReport.tsx | 12 +-- .../step/DynamicIOURequestStepReport.tsx | 12 +-- .../request/step/IOURequestStepUpgrade.tsx | 11 ++- .../actions/IOUTest/RejectMoneyRequestTest.ts | 94 +++++++++---------- tests/actions/ReportTest.ts | 88 +++++++++++++---- tests/actions/TransactionTest.ts | 13 ++- 16 files changed, 239 insertions(+), 142 deletions(-) diff --git a/src/components/Navigation/QuickCreationActionsBar/index.tsx b/src/components/Navigation/QuickCreationActionsBar/index.tsx index 01f9e617f35c..5f44c97ff093 100644 --- a/src/components/Navigation/QuickCreationActionsBar/index.tsx +++ b/src/components/Navigation/QuickCreationActionsBar/index.tsx @@ -99,18 +99,19 @@ function QuickCreationActionsBar() { return; } - const {reportID: createdReportID} = createNewReport( - currentUserPersonalDetails, - hasViolations, + const {reportID: createdReportID} = createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - defaultChatEnabledPolicy, - allBetas, + policy: defaultChatEnabledPolicy, + betas: allBetas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); // Navigate to the Reports page first so getCreateReportRoute() resolves against // the Search/Reports fullscreen context before opening the created report modal. Navigation.navigate(getReportsRootRoute()); diff --git a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx index 0d7e4d8d8766..5126ea89b2c1 100644 --- a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx +++ b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx @@ -83,18 +83,19 @@ function SearchActionsBarCreateButton() { return; } - const {reportID: createdReportID} = createNewReport( - currentUserPersonalDetails, - hasViolations, + const {reportID: createdReportID} = createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - defaultChatEnabledPolicy, - allBetas, + policy: defaultChatEnabledPolicy, + betas: allBetas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); Navigation.setNavigationActionToMicrotaskQueue(() => { Navigation.navigate( isSearchTopmostFullScreenRoute() diff --git a/src/hooks/useCreateNewReport.tsx b/src/hooks/useCreateNewReport.tsx index 25f683454be4..d2c978228090 100644 --- a/src/hooks/useCreateNewReport.tsx +++ b/src/hooks/useCreateNewReport.tsx @@ -36,18 +36,19 @@ function useCreateNewReport() { return useCallback( (policyID: string, shouldDismissEmptyReportsConfirmation = false) => { const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; - return createNewReport( - currentUserPersonalDetails, - hasViolations, + return createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, policy, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); }, [betas, currentUserPersonalDetails, hasViolations, isASAPSubmitBetaEnabled, policies, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber], ); diff --git a/src/libs/actions/IOU/Duplicate.ts b/src/libs/actions/IOU/Duplicate.ts index 91c2fbddf405..a7e9c572c325 100644 --- a/src/libs/actions/IOU/Duplicate.ts +++ b/src/libs/actions/IOU/Duplicate.ts @@ -1015,21 +1015,20 @@ function duplicateReport({ } const newReportName = translate('common.copyOfReportName', sourceReportName); - const {reportPreviewReportActionID, ...newReport} = createNewReport( + const {reportPreviewReportActionID, ...newReport} = createNewReport({ ownerPersonalDetails, - false, + hasViolationsParam: false, isASAPSubmitBetaEnabled, - targetPolicy, + policy: targetPolicy, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, - undefined, - { + options: { reportName: newReportName, }, - ); + }); const isCrossWorkspace = !!sourceReport && sourceReport.policyID !== targetPolicy.id; diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index d9327255d625..c7669e3af9d6 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -1609,10 +1609,22 @@ function rejectMoneyRequestsOnSearch({ existingRejectedReport = nextRejectedReport; }; for (const transactionID of selectedTransactionIDs) { - rejectMoneyRequest(transactionID, reportID, comment, policy, currentUserAccountIDParam, currentUserLogin, betas, delegateAccountID, formatPhoneNumber, getCurrencyDecimals, { - sharedRejectedToReportID, - existingRejectedReport, - setExistingRejectedReport, + rejectMoneyRequest({ + transactionID, + reportID, + comment, + policy, + currentUserAccountIDParam, + currentUserLogin, + betas, + delegateAccountID, + formatPhoneNumber, + getCurrencyDecimals, + options: { + sharedRejectedToReportID, + existingRejectedReport, + setExistingRejectedReport, + }, }); } } diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index 60e45e0f1346..9dfcec9a70ef 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -173,18 +173,19 @@ function EmptySearchViewContent({ return; } - const {reportID: createdReportID} = createNewReport( - currentUserPersonalDetails, - hasViolations, + const {reportID: createdReportID} = createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - defaultChatEnabledPolicy, + policy: defaultChatEnabledPolicy, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); Navigation.setNavigationActionToMicrotaskQueue(() => { Navigation.navigate( ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({ diff --git a/src/pages/Search/SearchTransactionsChangeReport.tsx b/src/pages/Search/SearchTransactionsChangeReport.tsx index 27bb22a3a74f..b8a6784f2b63 100644 --- a/src/pages/Search/SearchTransactionsChangeReport.tsx +++ b/src/pages/Search/SearchTransactionsChangeReport.tsx @@ -156,19 +156,19 @@ function SearchTransactionsChangeReport() { }, []); const createReportForPolicy = (shouldDismissEmptyReportsConfirmation?: boolean) => { - const optimisticReport = createNewReport( - targetOwnerPersonalDetails, - hasViolations, + const optimisticReport = createNewReport({ + ownerPersonalDetails: targetOwnerPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - policyForMovingExpenses, + policy: policyForMovingExpenses, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - {managedCardTransactionID}, - ); + options: {managedCardTransactionID}, + }); const policyTagList = policyForMovingExpenses?.id ? allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyForMovingExpenses.id}`] : {}; const reportsForCall = { ...reports, diff --git a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index 60b46fa0af0c..bc8c90f1003e 100644 --- a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -207,18 +207,19 @@ function AttachmentPickerWithMenuItems({ onConfirm: (shouldDismissEmptyReportsConfirmation) => selectOption( () => - createNewReport( - currentUserPersonalDetails, + createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - hasViolations, policy, betas, isTrackIntentUser, getCurrencyDecimals, - true, + shouldNotifyNewAction: true, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ), + options: {}, + }), true, ), }); @@ -227,7 +228,19 @@ function AttachmentPickerWithMenuItems({ if (shouldShowEmptyReportConfirmation) { openCreateReportConfirmation(); } else { - createNewReport(currentUserPersonalDetails, isASAPSubmitBetaEnabled, hasViolations, policy, betas, isTrackIntentUser, getCurrencyDecimals, true, formatPhoneNumber, false); + createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, + isASAPSubmitBetaEnabled, + policy, + betas, + isTrackIntentUser, + getCurrencyDecimals, + shouldNotifyNewAction: true, + formatPhoneNumber, + shouldDismissEmptyReportsConfirmation: false, + options: {}, + }); } }; diff --git a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx index 10e323f6d403..380e52adcf31 100644 --- a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx +++ b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx @@ -85,18 +85,19 @@ function CreateReportMenuItem() { clearLastSearchParams(); } - const {reportID: createdReportID} = createNewReport( - currentUserPersonalDetails, - hasViolations, + const {reportID: createdReportID} = createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - defaultChatEnabledPolicy, - allBetas, + policy: defaultChatEnabledPolicy, + betas: allBetas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); // Navigate to the Reports page first so getCreateReportRoute() resolves against // the Search/Reports fullscreen context before opening the created report modal. Navigation.navigate(getReportsRootRoute(), {forceReplace: isReportInSearch}); diff --git a/src/pages/iou/RejectReasonPage.tsx b/src/pages/iou/RejectReasonPage.tsx index fd12ed487334..5df49a7b117f 100644 --- a/src/pages/iou/RejectReasonPage.tsx +++ b/src/pages/iou/RejectReasonPage.tsx @@ -53,18 +53,18 @@ function RejectReasonPage({route}: RejectReasonPageProps) { return; } - const urlToNavigateBack = rejectMoneyRequest( + const urlToNavigateBack = rejectMoneyRequest({ transactionID, reportID, - values.comment, + comment: values.comment, policy, - currentUserAccountID, - currentUserLogin ?? '', + currentUserAccountIDParam: currentUserAccountID, + currentUserLogin: currentUserLogin ?? '', betas, delegateAccountID, formatPhoneNumber, getCurrencyDecimals, - ); + }); removeTransaction(transactionID); // If the super wide rhp is not opened, dismiss the entire modal. if (superWideRHPRouteKeys.length > 0) { diff --git a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx index 41d77924ab62..7cc4de88d743 100644 --- a/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx +++ b/src/pages/iou/request/step/DynamicIOURequestEditReport.tsx @@ -168,19 +168,19 @@ function DynamicIOURequestEditReport({route}: DynamicIOURequestEditReportProps) return; } - const optimisticReport = createNewReport( + const optimisticReport = createNewReport({ ownerPersonalDetails, - hasViolations, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - policyForMovingExpenses, + policy: policyForMovingExpenses, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - {managedCardTransactionID}, - ); + options: {managedCardTransactionID}, + }); selectReport( { value: optimisticReport.reportID, diff --git a/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx b/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx index 2b8927cd0150..bf6cd5201d83 100644 --- a/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx +++ b/src/pages/iou/request/step/DynamicIOURequestStepReport.tsx @@ -175,19 +175,19 @@ function DynamicIOURequestStepReport({route, transaction}: DynamicIOURequestStep } const policyForNewReport = isPerDiemTransaction && perDiemOriginalPolicy ? perDiemOriginalPolicy : policyForMovingExpenses; - const optimisticReport = createNewReport( + const optimisticReport = createNewReport({ ownerPersonalDetails, - hasViolations, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - policyForNewReport, + policy: policyForNewReport, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, shouldDismissEmptyReportsConfirmation, - {managedCardTransactionID: isUnreportedManagedCardTransaction ? transactionID : undefined}, - ); + options: {managedCardTransactionID: isUnreportedManagedCardTransaction ? transactionID : undefined}, + }); handleRegularReportSelection({value: optimisticReport.reportID, keyForList: optimisticReport.reportID, policyID: policyForNewReport?.id}, optimisticReport); }; diff --git a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx index 72761251f380..5f540cd10aae 100644 --- a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx +++ b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx @@ -142,17 +142,18 @@ function IOURequestStepUpgrade({ if (upgradePath === CONST.UPGRADE_PATHS.REPORTS && policyID && selectedTransactionsKeys.includes(transactionID)) { const newPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; - const optimisticReport = createNewReport( + const optimisticReport = createNewReport({ ownerPersonalDetails, - hasViolations, + hasViolationsParam: hasViolations, isASAPSubmitBetaEnabled, - newPolicy, + policy: newPolicy, betas, isTrackIntentUser, getCurrencyDecimals, - false, + shouldNotifyNewAction: false, formatPhoneNumber, - ); + options: {}, + }); const policyTagList = policyID ? allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] : {}; const reportsForCall = { diff --git a/tests/actions/IOUTest/RejectMoneyRequestTest.ts b/tests/actions/IOUTest/RejectMoneyRequestTest.ts index 88a133a755ca..936806bd573d 100644 --- a/tests/actions/IOUTest/RejectMoneyRequestTest.ts +++ b/tests/actions/IOUTest/RejectMoneyRequestTest.ts @@ -154,18 +154,18 @@ describe('actions/IOU/RejectMoneyRequest', () => { if (!transaction?.transactionID || !iouReport?.reportID) { throw new Error('Required transaction or report data is missing'); } - const result = rejectMoneyRequest( - transaction.transactionID, - iouReport.reportID, + const result = rejectMoneyRequest({ + transactionID: transaction.transactionID, + reportID: iouReport.reportID, comment, policy, - TEST_USER_ACCOUNT_ID, - TEST_USER_EMAIL, - [CONST.BETAS.ALL], - undefined, + currentUserAccountIDParam: TEST_USER_ACCOUNT_ID, + currentUserLogin: TEST_USER_EMAIL, + betas: [CONST.BETAS.ALL], + delegateAccountID: undefined, formatPhoneNumber, - getCurrencyDecimalsLocal, - ); + getCurrencyDecimals: getCurrencyDecimalsLocal, + }); // Then: Should return navigation route to chat report expect(result).toBe(ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID)); @@ -181,18 +181,18 @@ describe('actions/IOU/RejectMoneyRequest', () => { if (!transaction?.transactionID || !iouReport?.reportID) { throw new Error('Required transaction or report data is missing'); } - rejectMoneyRequest( - transaction.transactionID, - iouReport.reportID, + rejectMoneyRequest({ + transactionID: transaction.transactionID, + reportID: iouReport.reportID, comment, policy, - TEST_USER_ACCOUNT_ID, - TEST_USER_EMAIL, - [CONST.BETAS.ALL], - undefined, + currentUserAccountIDParam: TEST_USER_ACCOUNT_ID, + currentUserLogin: TEST_USER_EMAIL, + betas: [CONST.BETAS.ALL], + delegateAccountID: undefined, formatPhoneNumber, - getCurrencyDecimalsLocal, - ); + getCurrencyDecimals: getCurrencyDecimalsLocal, + }); await waitForBatchedUpdates(); // Then: Verify violation is added @@ -248,18 +248,18 @@ describe('actions/IOU/RejectMoneyRequest', () => { if (!transaction?.transactionID || !iouReport?.reportID) { throw new Error('Required transaction or report data is missing'); } - rejectMoneyRequest( - transaction.transactionID, - iouReport.reportID, + rejectMoneyRequest({ + transactionID: transaction.transactionID, + reportID: iouReport.reportID, comment, policy, - TEST_USER_ACCOUNT_ID, - TEST_USER_EMAIL, - [CONST.BETAS.ALL], - undefined, + currentUserAccountIDParam: TEST_USER_ACCOUNT_ID, + currentUserLogin: TEST_USER_EMAIL, + betas: [CONST.BETAS.ALL], + delegateAccountID: undefined, formatPhoneNumber, - getCurrencyDecimalsLocal, - ); + getCurrencyDecimals: getCurrencyDecimalsLocal, + }); await waitForBatchedUpdates(); // Then: createdIOUReportActionID shouldn't be undefined @@ -298,41 +298,41 @@ describe('actions/IOU/RejectMoneyRequest', () => { throw new Error('Required transaction or report data is missing'); } - rejectMoneyRequest( - transaction.transactionID, - iouReport.reportID, + rejectMoneyRequest({ + transactionID: transaction.transactionID, + reportID: iouReport.reportID, comment, policy, - TEST_USER_ACCOUNT_ID, - TEST_USER_EMAIL, - [CONST.BETAS.ALL], - undefined, + currentUserAccountIDParam: TEST_USER_ACCOUNT_ID, + currentUserLogin: TEST_USER_EMAIL, + betas: [CONST.BETAS.ALL], + delegateAccountID: undefined, formatPhoneNumber, - getCurrencyDecimalsLocal, - { + getCurrencyDecimals: getCurrencyDecimalsLocal, + options: { sharedRejectedToReportID, existingRejectedReport, setExistingRejectedReport, }, - ); + }); - rejectMoneyRequest( - secondTransaction.transactionID, - iouReport.reportID, + rejectMoneyRequest({ + transactionID: secondTransaction.transactionID, + reportID: iouReport.reportID, comment, policy, - TEST_USER_ACCOUNT_ID, - TEST_USER_EMAIL, - [CONST.BETAS.ALL], - undefined, + currentUserAccountIDParam: TEST_USER_ACCOUNT_ID, + currentUserLogin: TEST_USER_EMAIL, + betas: [CONST.BETAS.ALL], + delegateAccountID: undefined, formatPhoneNumber, - getCurrencyDecimalsLocal, - { + getCurrencyDecimals: getCurrencyDecimalsLocal, + options: { sharedRejectedToReportID, existingRejectedReport, setExistingRejectedReport, }, - ); + }); await waitForBatchedUpdates(); let allReports: OnyxCollection; diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index dd1a4012974c..928d5fde13ae 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -2791,7 +2791,18 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); mockFetchData.pause(); - const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); + const {reportID} = Report.createNewReport({ + ownerPersonalDetails: {accountID}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: {}, + }); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); const reportPreviewAction = await new Promise>>((resolve) => { @@ -2857,8 +2868,19 @@ describe('actions/Report', () => { type: CONST.POLICY.TYPE.TEAM, }; - Report.createNewReport({accountID: 1234}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber, undefined, { - managedCardTransactionID, + Report.createNewReport({ + ownerPersonalDetails: {accountID: 1234}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: { + managedCardTransactionID, + }, }); expect(apiWriteSpy).toHaveBeenCalledWith(WRITE_COMMANDS.CREATE_APP_REPORT, expect.objectContaining({managedCardTransactionID}), expect.anything()); @@ -2880,7 +2902,18 @@ describe('actions/Report', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); mockFetchData.pause(); - Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); + Report.createNewReport({ + ownerPersonalDetails: {accountID}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: {}, + }); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); await new Promise((resolve) => { @@ -2918,7 +2951,18 @@ describe('actions/Report', () => { } // When create new report - Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); + Report.createNewReport({ + ownerPersonalDetails: {accountID}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: {}, + }); // Then the parent report's hasOutstandingChildRequest property should remain unchanged await new Promise((resolve) => { @@ -2953,17 +2997,18 @@ describe('actions/Report', () => { } // When create new report - const optimisticReportData = Report.createNewReport( - {accountID}, - true, - false, + const optimisticReportData = Report.createNewReport({ + ownerPersonalDetails: {accountID}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, policy, - [CONST.BETAS.ALL], - false, - TestHelper.getCurrencyDecimalsLocal, - false, - TestHelper.formatPhoneNumber, - ); + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: {}, + }); await waitForBatchedUpdates(); // Then the report's status should be draft. @@ -3005,7 +3050,18 @@ describe('actions/Report', () => { }; await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); - const {reportID} = Report.createNewReport({accountID}, true, false, policy, [CONST.BETAS.ALL], false, TestHelper.getCurrencyDecimalsLocal, false, TestHelper.formatPhoneNumber); + const {reportID} = Report.createNewReport({ + ownerPersonalDetails: {accountID}, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: TestHelper.getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber: TestHelper.formatPhoneNumber, + options: {}, + }); const parentReport = ReportUtils.getPolicyExpenseChat(accountID, policyID); await waitForBatchedUpdates(); diff --git a/tests/actions/TransactionTest.ts b/tests/actions/TransactionTest.ts index f5bc73daf957..40a244afc811 100644 --- a/tests/actions/TransactionTest.ts +++ b/tests/actions/TransactionTest.ts @@ -215,7 +215,18 @@ describe('actions/Transaction', () => { await waitForBatchedUpdates(); - createNewReport(creatorPersonalDetails, true, false, mockPolicy, [CONST.BETAS.ALL], false, getCurrencyDecimalsLocal, false, formatPhoneNumber); + createNewReport({ + ownerPersonalDetails: creatorPersonalDetails, + hasViolationsParam: true, + isASAPSubmitBetaEnabled: false, + policy: mockPolicy, + betas: [CONST.BETAS.ALL], + isTrackIntentUser: false, + getCurrencyDecimals: getCurrencyDecimalsLocal, + shouldNotifyNewAction: false, + formatPhoneNumber, + options: {}, + }); // Create a tracked expense const selfDMReport: Report = { ...createRandomReport(1, CONST.REPORT.CHAT_TYPE.SELF_DM), From bdc0efd14e73e08f3be62f27bd3b122da328819d Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 13 Aug 2026 17:36:41 +0430 Subject: [PATCH 10/19] Fix React Compiler deps for phone formatting --- src/components/Navigation/QuickCreationActionsBar/index.tsx | 2 +- .../Search/SearchPageHeader/SearchActionsBarCreateButton.tsx | 2 +- .../ReportActionCompose/AttachmentPickerWithMenuItems.tsx | 1 + src/pages/iou/request/step/IOURequestStepUpgrade.tsx | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Navigation/QuickCreationActionsBar/index.tsx b/src/components/Navigation/QuickCreationActionsBar/index.tsx index 5f44c97ff093..1d30b99d2400 100644 --- a/src/components/Navigation/QuickCreationActionsBar/index.tsx +++ b/src/components/Navigation/QuickCreationActionsBar/index.tsx @@ -119,7 +119,7 @@ function QuickCreationActionsBar() { Navigation.navigate(getCreateReportRoute({reportID: createdReportID})); }); }, - [currentUserPersonalDetails, hasViolations, defaultChatEnabledPolicy, isASAPSubmitBetaEnabled, allBetas, isTrackIntentUser, getCurrencyDecimals], + [currentUserPersonalDetails, hasViolations, defaultChatEnabledPolicy, isASAPSubmitBetaEnabled, allBetas, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber], ); const {openCreateReportConfirmation} = useCreateEmptyReportConfirmation({ diff --git a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx index 5126ea89b2c1..560ecb3b2d40 100644 --- a/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx +++ b/src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx @@ -104,7 +104,7 @@ function SearchActionsBarCreateButton() { ); }); }, - [currentUserPersonalDetails, hasViolations, defaultChatEnabledPolicy, isASAPSubmitBetaEnabled, allBetas, isTrackIntentUser, getCurrencyDecimals], + [currentUserPersonalDetails, hasViolations, defaultChatEnabledPolicy, isASAPSubmitBetaEnabled, allBetas, isTrackIntentUser, getCurrencyDecimals, formatPhoneNumber], ); const {openCreateReportConfirmation} = useCreateEmptyReportConfirmation({ diff --git a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index bc8c90f1003e..2e5444538ef6 100644 --- a/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -349,6 +349,7 @@ function AttachmentPickerWithMenuItems({ icons, betas, draftTransactionIDs, + formatPhoneNumber, ]); const createReportOption: PopoverMenuItem[] = useMemo(() => { diff --git a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx index 5f540cd10aae..0fe64be6a629 100644 --- a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx +++ b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx @@ -288,6 +288,7 @@ function IOURequestStepUpgrade({ isTrackIntentUser, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, ]); const participant = transaction?.participants?.[0]; From 9f95689b34a536b1e88c112870535d669e44cbfd Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Mon, 17 Aug 2026 15:14:15 +0430 Subject: [PATCH 11/19] Fix report creation type errors in search router and IOU tests --- .../useCreateNavigationSuggestions.ts | 20 ++++++++++--------- tests/actions/IOUTest/HoldTest.ts | 5 +++++ tests/actions/IOUTest/PayMoneyRequestTest.ts | 1 + tests/actions/IOUTest/ReportWorkflowTest.ts | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/Search/SearchRouter/useCreateNavigationSuggestions.ts b/src/components/Search/SearchRouter/useCreateNavigationSuggestions.ts index ff9f2dbd0ab3..d0ecdb39dedc 100644 --- a/src/components/Search/SearchRouter/useCreateNavigationSuggestions.ts +++ b/src/components/Search/SearchRouter/useCreateNavigationSuggestions.ts @@ -73,7 +73,7 @@ function replaceTopmostModalWithAction(action: () => void) { } function useCreateNavigationSuggestions(query = ''): NavigationSuggestionSourceItem[] { - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const icons = useMemoizedLazyExpensifyIcons(['Coins', 'Receipt', 'Cash', 'Transfer', 'MoneyCircle', 'Location', 'Document', 'ChatBubble', 'InvoiceGeneric', 'NewWorkspace']); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {getCurrencyDecimals} = useCurrencyListActions(); @@ -122,17 +122,19 @@ function useCreateNavigationSuggestions(query = ''): NavigationSuggestionSourceI clearLastSearchParams(); } - const {reportID: createdReportID} = createNewReport( - currentUserPersonalDetails, - false, - isBetaEnabled(CONST.BETAS.ASAP_SUBMIT), - defaultChatEnabledPolicy, - allBetas, + const {reportID: createdReportID} = createNewReport({ + ownerPersonalDetails: currentUserPersonalDetails, + hasViolationsParam: false, + isASAPSubmitBetaEnabled: isBetaEnabled(CONST.BETAS.ASAP_SUBMIT), + policy: defaultChatEnabledPolicy, + betas: allBetas, isTrackIntentUser, getCurrencyDecimals, - false, + formatPhoneNumber, + shouldNotifyNewAction: false, shouldDismissEmptyReportsConfirmation, - ); + options: {}, + }); // Navigate to the Reports page first so getCreateReportRoute() resolves against // the Search/Reports fullscreen context before opening the created report modal. Navigation.navigate(getReportsRootRoute(), {forceReplace: isReportInSearch}); diff --git a/tests/actions/IOUTest/HoldTest.ts b/tests/actions/IOUTest/HoldTest.ts index 9c9c9e895337..3a3c6d9986a4 100644 --- a/tests/actions/IOUTest/HoldTest.ts +++ b/tests/actions/IOUTest/HoldTest.ts @@ -908,6 +908,7 @@ describe('actions/IOU/Hold', () => { betas: [], delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, shouldMoveHeldTransactions: false, shouldMoveScanFailedTransactions: true, }); @@ -950,6 +951,7 @@ describe('actions/IOU/Hold', () => { betas: [], delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, shouldMoveHeldTransactions: false, shouldMoveScanFailedTransactions: true, }); @@ -977,6 +979,7 @@ describe('actions/IOU/Hold', () => { betas: [], delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); expect(result.successData).not.toEqual( @@ -999,6 +1002,7 @@ describe('actions/IOU/Hold', () => { betas: [], delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); const transactionUpdate = result.optimisticData.find((entry) => entry.onyxMethod === Onyx.METHOD.MERGE_COLLECTION && entry.key === ONYXKEYS.COLLECTION.TRANSACTION); @@ -1020,6 +1024,7 @@ describe('actions/IOU/Hold', () => { betas: [], delegateAccountID: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, shouldMoveHeldTransactions: false, shouldMoveScanFailedTransactions: true, }); diff --git a/tests/actions/IOUTest/PayMoneyRequestTest.ts b/tests/actions/IOUTest/PayMoneyRequestTest.ts index d32004d403ba..f576e2d82c37 100644 --- a/tests/actions/IOUTest/PayMoneyRequestTest.ts +++ b/tests/actions/IOUTest/PayMoneyRequestTest.ts @@ -1092,6 +1092,7 @@ describe('actions/IOU/PayMoneyRequest', () => { isTrackIntentUser: false, conciergeChat: undefined, getCurrencyDecimals: getCurrencyDecimalsLocal, + formatPhoneNumber, }); it('moves the scan-failed expense to a new report when another expense is being paid', async () => { diff --git a/tests/actions/IOUTest/ReportWorkflowTest.ts b/tests/actions/IOUTest/ReportWorkflowTest.ts index 494bfb70a5af..f7c67e41629a 100644 --- a/tests/actions/IOUTest/ReportWorkflowTest.ts +++ b/tests/actions/IOUTest/ReportWorkflowTest.ts @@ -2544,6 +2544,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, isTrackIntentUser: false, ownerLogin: undefined, + formatPhoneNumber, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic/failure data structure From 805e31bcfd24346a827ee2e6eb5def41915e868d Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Mon, 17 Aug 2026 15:40:21 +0430 Subject: [PATCH 12/19] resolved the lint errors --- src/hooks/useSearchBulkActions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index 003cb7d65dfb..825b19e404c7 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -1557,6 +1557,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { isTrackIntentUser, conciergeChat, getCurrencyDecimals, + formatPhoneNumber, ], ); From f03337a94b4aa9c98d90ddf72855ab1c30f43ea9 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Mon, 17 Aug 2026 17:52:32 +0430 Subject: [PATCH 13/19] Fix useCreateNavigationSuggestions test expectation --- tests/unit/useCreateNavigationSuggestionsTest.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/unit/useCreateNavigationSuggestionsTest.ts b/tests/unit/useCreateNavigationSuggestionsTest.ts index 204e012799a8..1c0849d87803 100644 --- a/tests/unit/useCreateNavigationSuggestionsTest.ts +++ b/tests/unit/useCreateNavigationSuggestionsTest.ts @@ -338,7 +338,21 @@ describe('useCreateNavigationSuggestions', () => { const onCreateReport = mockUseCreateReport.mock.calls.at(0)?.at(0)?.onCreateReport; act(() => onCreateReport?.(true)); - expect(createNewReport).toHaveBeenCalledWith(expect.anything(), false, true, submitPolicy, [], false, mockGetCurrencyDecimals, false, true); + expect(createNewReport).toHaveBeenCalledWith( + expect.objectContaining({ + ownerPersonalDetails: expect.anything(), + hasViolationsParam: false, + isASAPSubmitBetaEnabled: true, + policy: submitPolicy, + betas: [], + isTrackIntentUser: false, + getCurrencyDecimals: mockGetCurrencyDecimals, + formatPhoneNumber: undefined, + shouldNotifyNewAction: false, + shouldDismissEmptyReportsConfirmation: true, + options: {}, + }), + ); expect(clearLastSearchParams).not.toHaveBeenCalled(); expect(Navigation.navigate).toHaveBeenNthCalledWith(1, 'reports', {forceReplace: false}); expect(Navigation.navigate).toHaveBeenNthCalledWith(2, 'report/created-report', {forceReplace: false}); From 38106727c84f808fe66ec26492067e025041cf47 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 18 Aug 2026 12:02:05 +0430 Subject: [PATCH 14/19] fix eslint unsafe any in create navigation suggestions test --- tests/unit/useCreateNavigationSuggestionsTest.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/useCreateNavigationSuggestionsTest.ts b/tests/unit/useCreateNavigationSuggestionsTest.ts index 1c0849d87803..d824aab8180b 100644 --- a/tests/unit/useCreateNavigationSuggestionsTest.ts +++ b/tests/unit/useCreateNavigationSuggestionsTest.ts @@ -340,7 +340,10 @@ describe('useCreateNavigationSuggestions', () => { expect(createNewReport).toHaveBeenCalledWith( expect.objectContaining({ - ownerPersonalDetails: expect.anything(), + ownerPersonalDetails: expect.objectContaining({ + accountID: 1, + login: 'test@example.com', + }), hasViolationsParam: false, isASAPSubmitBetaEnabled: true, policy: submitPolicy, From 75ee9cdf271f439050ff3538f9c071344c02d608 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 18 Aug 2026 14:44:09 +0430 Subject: [PATCH 15/19] refactor report and search action params --- src/libs/actions/IOU/RejectMoneyRequest.ts | 27 ++++++----- src/libs/actions/Report/index.ts | 28 +++++------ src/libs/actions/Search.ts | 55 +++++++++++----------- 3 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index 854cf9930336..fdffbaac1302 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -944,6 +944,19 @@ function prepareRejectMoneyRequestData({ return {optimisticData, successData, failureData, parameters, urlToNavigateBack: urlToNavigateBack as Route}; } +type RejectMoneyRequestParams = { + transactionID: string; + reportID: string; + comment: string; + policy: OnyxEntry; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + options?: RejectMoneyRequestOptions; +}; function rejectMoneyRequest({ transactionID, @@ -957,19 +970,7 @@ function rejectMoneyRequest({ formatPhoneNumber, getCurrencyDecimals, options, -}: { - transactionID: string; - reportID: string; - comment: string; - policy: OnyxEntry; - currentUserAccountIDParam: number; - currentUserLogin: string; - betas: OnyxEntry; - delegateAccountID: number | undefined; - formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; - options?: RejectMoneyRequestOptions; -}): Route | undefined { +}: RejectMoneyRequestParams): Route | undefined { const data = prepareRejectMoneyRequestData({ transactionID, reportID, diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index 18c6cf89185e..de7ee81a0985 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4527,6 +4527,19 @@ function buildNewReportOptimisticData({ optimisticReportData, }; } +type CreateNewReportParams = { + ownerPersonalDetails: CurrentUserPersonalDetails; + hasViolationsParam: boolean; + isASAPSubmitBetaEnabled: boolean; + policy: OnyxEntry; + betas: OnyxEntry; + isTrackIntentUser: boolean | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + shouldNotifyNewAction: boolean; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + shouldDismissEmptyReportsConfirmation?: boolean; + options: {managedCardTransactionID?: string; reportName?: string}; +}; function createNewReport({ ownerPersonalDetails, @@ -4540,19 +4553,7 @@ function createNewReport({ formatPhoneNumber, shouldDismissEmptyReportsConfirmation, options = {}, -}: { - ownerPersonalDetails: CurrentUserPersonalDetails; - hasViolationsParam: boolean; - isASAPSubmitBetaEnabled: boolean; - policy: OnyxEntry; - betas: OnyxEntry; - isTrackIntentUser: boolean | undefined; - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; - shouldNotifyNewAction: boolean; - formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; - shouldDismissEmptyReportsConfirmation?: boolean; - options: {managedCardTransactionID?: string; reportName?: string}; -}) { +}: CreateNewReportParams) { const {managedCardTransactionID, reportName} = options; const optimisticReportID = generateReportID(); const reportActionID = rand64(); @@ -5341,7 +5342,6 @@ function buildInviteToRoomOnyxData( key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { participants: newParticipantAccountCleanUp, - pendingAction: null, }, }, { diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index d06e35a2f6ac..1771ea9531af 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -1567,7 +1567,19 @@ function exportToIntegrationOnSearch(hash: number, reportIDs: string[], connecti finallyData, }); } - +type RejectMoneyRequestInBulkParams = { + reportID: string; + comment: string; + policy: OnyxEntry; + transactionIDs: string[]; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + hash?: number; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; +}; function rejectMoneyRequestInBulk({ reportID, comment, @@ -1580,19 +1592,7 @@ function rejectMoneyRequestInBulk({ getCurrencyDecimals, hash, formatPhoneNumber, -}: { - reportID: string; - comment: string; - policy: OnyxEntry; - transactionIDs: string[]; - currentUserAccountIDParam: number; - currentUserLogin: string; - betas: OnyxEntry; - delegateAccountID: number | undefined; - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; - hash?: number; - formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; -}) { +}: RejectMoneyRequestInBulkParams) { const optimisticData: Array> = []; const finallyData: Array> = []; const successData: RejectMoneyRequestData['successData'] = []; @@ -1649,6 +1649,19 @@ function rejectMoneyRequestInBulk({ type TransactionReportInfo = { reportID?: string; }; +type RejectMoneyRequestsOnSearchParams = { + hash: number; + selectedTransactions: Record; + comment: string; + allPolicies: OnyxCollection; + allReports: OnyxCollection; + currentUserAccountIDParam: number; + currentUserLogin: string; + betas: OnyxEntry; + delegateAccountID: number | undefined; + getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; +}; function rejectMoneyRequestsOnSearch({ hash, @@ -1662,19 +1675,7 @@ function rejectMoneyRequestsOnSearch({ delegateAccountID, getCurrencyDecimals, formatPhoneNumber, -}: { - hash: number; - selectedTransactions: Record; - comment: string; - allPolicies: OnyxCollection; - allReports: OnyxCollection; - currentUserAccountIDParam: number; - currentUserLogin: string; - betas: OnyxEntry; - delegateAccountID: number | undefined; - getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; - formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; -}) { +}: RejectMoneyRequestsOnSearchParams) { const transactionIDs = Object.keys(selectedTransactions); const transactionsByReport = transactionIDs.reduce>((acc, transactionID) => { From 3a68d85f912de85b2a93e81bdabd991f807f71d1 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 18 Aug 2026 14:58:03 +0430 Subject: [PATCH 16/19] docs: add field comments for action param types --- src/libs/actions/IOU/RejectMoneyRequest.ts | 11 +++++++++++ src/libs/actions/Report/index.ts | 11 +++++++++++ src/libs/actions/Search.ts | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index fdffbaac1302..c2da18d87828 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -945,16 +945,27 @@ function prepareRejectMoneyRequestData({ return {optimisticData, successData, failureData, parameters, urlToNavigateBack: urlToNavigateBack as Route}; } type RejectMoneyRequestParams = { + /** Transaction being rejected. */ transactionID: string; + /** Report that owns the transaction. */ reportID: string; + /** Parsed comment sent with the rejection. */ comment: string; + /** Policy used to resolve permissions and delayed submission behavior. */ policy: OnyxEntry; + /** Current user's account ID used for optimistic report updates. */ currentUserAccountIDParam: number; + /** Current user's login used for optimistic personal details updates. */ currentUserLogin: string; + /** Beta flags used to decide which rejection behavior is available. */ betas: OnyxEntry; + /** Delegate account ID used when acting on behalf of another user. */ delegateAccountID: number | undefined; + /** Formatter used when building optimistic personal details. */ formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + /** Currency helper used for optimistic monetary formatting. */ getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + /** Optional flags that alter the rejection flow. */ options?: RejectMoneyRequestOptions; }; diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index de7ee81a0985..f99adaff75ed 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4528,16 +4528,27 @@ function buildNewReportOptimisticData({ }; } type CreateNewReportParams = { + /** Personal details for the user creating the report. */ ownerPersonalDetails: CurrentUserPersonalDetails; + /** Whether the draft report has policy violations. */ hasViolationsParam: boolean; + /** Whether ASAP submit is available for this policy. */ isASAPSubmitBetaEnabled: boolean; + /** Policy used to build the report and optimistic data. */ policy: OnyxEntry; + /** Beta flags used when creating the report. */ betas: OnyxEntry; + /** Whether the user is a tracked intent user. */ isTrackIntentUser: boolean | undefined; + /** Currency helper used for optimistic report formatting. */ getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + /** Whether the new report should trigger a new action notification. */ shouldNotifyNewAction: boolean; + /** Formatter used for phone numbers in optimistic report data. */ formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; + /** Whether the empty reports confirmation should be dismissed. */ shouldDismissEmptyReportsConfirmation?: boolean; + /** Optional managed card transaction and report name overrides. */ options: {managedCardTransactionID?: string; reportName?: string}; }; diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 1771ea9531af..3dbb73598556 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -1568,16 +1568,27 @@ function exportToIntegrationOnSearch(hash: number, reportIDs: string[], connecti }); } type RejectMoneyRequestInBulkParams = { + /** Report where the selected expenses belong. */ reportID: string; + /** Parsed comment included with each rejection. */ comment: string; + /** Policy used to determine delayed submission behavior. */ policy: OnyxEntry; + /** Transaction IDs being rejected in bulk. */ transactionIDs: string[]; + /** Current user's account ID used for optimistic updates. */ currentUserAccountIDParam: number; + /** Current user's login used for optimistic personal details updates. */ currentUserLogin: string; + /** Beta flags used to determine available rejection behavior. */ betas: OnyxEntry; + /** Delegate account ID used when acting on behalf of another user. */ delegateAccountID: number | undefined; + /** Currency helper used for optimistic monetary formatting. */ getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + /** Snapshot hash used to merge loading data into the search result. */ hash?: number; + /** Formatter used when building optimistic personal details. */ formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function rejectMoneyRequestInBulk({ @@ -1650,16 +1661,27 @@ type TransactionReportInfo = { reportID?: string; }; type RejectMoneyRequestsOnSearchParams = { + /** Search snapshot hash used for loading state. */ hash: number; + /** Selected transactions mapped to their report metadata. */ selectedTransactions: Record; + /** Parsed comment included with each rejection. */ comment: string; + /** All policies available in Onyx for resolving report policy data. */ allPolicies: OnyxCollection; + /** All reports available in Onyx for resolving report metadata. */ allReports: OnyxCollection; + /** Current user's account ID used for optimistic updates. */ currentUserAccountIDParam: number; + /** Current user's login used for optimistic personal details updates. */ currentUserLogin: string; + /** Beta flags used to determine available rejection behavior. */ betas: OnyxEntry; + /** Delegate account ID used when acting on behalf of another user. */ delegateAccountID: number | undefined; + /** Currency helper used for optimistic monetary formatting. */ getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + /** Formatter used when building optimistic personal details. */ formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; From 6032d72b9cceb513c8aa1ae941f99c1d59cc3436 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 18 Aug 2026 15:18:02 +0430 Subject: [PATCH 17/19] chore: rename RejectMoneyRequest param type --- src/libs/actions/IOU/RejectMoneyRequest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU/RejectMoneyRequest.ts b/src/libs/actions/IOU/RejectMoneyRequest.ts index c2da18d87828..7723fd5b6057 100644 --- a/src/libs/actions/IOU/RejectMoneyRequest.ts +++ b/src/libs/actions/IOU/RejectMoneyRequest.ts @@ -944,7 +944,7 @@ function prepareRejectMoneyRequestData({ return {optimisticData, successData, failureData, parameters, urlToNavigateBack: urlToNavigateBack as Route}; } -type RejectMoneyRequestParams = { +type RejectMoneyRequest = { /** Transaction being rejected. */ transactionID: string; /** Report that owns the transaction. */ @@ -981,7 +981,7 @@ function rejectMoneyRequest({ formatPhoneNumber, getCurrencyDecimals, options, -}: RejectMoneyRequestParams): Route | undefined { +}: RejectMoneyRequest): Route | undefined { const data = prepareRejectMoneyRequestData({ transactionID, reportID, From c6335e89459dac60330c2a9e2509e79cde00dae7 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 20 Aug 2026 14:11:51 +0430 Subject: [PATCH 18/19] fix: pass formatPhoneNumber to report workflow --- src/libs/actions/IOU/ReportWorkflow.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/IOU/ReportWorkflow.ts b/src/libs/actions/IOU/ReportWorkflow.ts index 6b14d801098b..7a4aa01504a6 100644 --- a/src/libs/actions/IOU/ReportWorkflow.ts +++ b/src/libs/actions/IOU/ReportWorkflow.ts @@ -148,6 +148,7 @@ type SubmitReportFunctionParams = { */ shouldExportToPDF?: boolean; getCurrencyDecimals: CurrencyListActionsContextType['getCurrencyDecimals']; + formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }; function canApproveIOU( @@ -1324,6 +1325,7 @@ function submitReport({ shouldExportToPDF, isTrackIntentUser, getCurrencyDecimals, + formatPhoneNumber, }: SubmitReportFunctionParams) { if (!expenseReport) { return; @@ -1606,6 +1608,7 @@ function submitReport({ betas, delegateAccountID, getCurrencyDecimals, + formatPhoneNumber, }); optimisticData.push(...holdReportOnyxData.optimisticData); From fc1d697bb236ee43e6ac9567c2f5b054a3882a55 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 20 Aug 2026 14:56:11 +0430 Subject: [PATCH 19/19] Fix TypeScript errors in report workflow actions --- .../SubmitPrimaryAction.tsx | 3 ++- .../SubmitActionButton.tsx | 3 ++- src/hooks/useLifecycleActions.tsx | 1 + src/pages/ReportSubmitToContent.tsx | 3 ++- tests/actions/IOUTest/ReportWorkflowTest.ts | 24 +++++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx b/src/components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx index 1e998090ca5b..a070362af6bf 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx +++ b/src/components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx @@ -69,7 +69,7 @@ function SubmitPrimaryAction({reportID}: SubmitPrimaryActionProps) { function SubmitPrimaryActionContent({reportID}: SubmitPrimaryActionProps) { const {isSubmittingAnimationRunning, stopAnimation, startSubmittingAnimation} = usePaymentAnimationsContext(); - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {isOffline} = useNetwork(); const {accountID, email} = useCurrentUserPersonalDetails(); @@ -195,6 +195,7 @@ function SubmitPrimaryActionContent({reportID}: SubmitPrimaryActionProps) { // Submit via PDF submits the report to the submitter (self); the backend keys off this to generate the PDF. managerEmail: shouldExportToPDF ? email : undefined, isTrackIntentUser, + formatPhoneNumber, }); if (currentSearchQueryJSON && !isOffline) { search({ diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/SubmitActionButton.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/SubmitActionButton.tsx index 1ed31c1323c0..096bcfac47d5 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/SubmitActionButton.tsx +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/SubmitActionButton.tsx @@ -50,7 +50,7 @@ function SubmitActionButton() { } function SubmitActionButtonContent() { - const {translate} = useLocalize(); + const {translate, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const {showConfirmModal} = useConfirmModal(); const currentUserDetails = useCurrentUserPersonalDetails(); @@ -132,6 +132,7 @@ function SubmitActionButtonContent() { delegateAccountID, submitterLogin, isTrackIntentUser, + formatPhoneNumber, }); }); }; diff --git a/src/hooks/useLifecycleActions.tsx b/src/hooks/useLifecycleActions.tsx index 077f53328ec9..ea7ac8890f0f 100644 --- a/src/hooks/useLifecycleActions.tsx +++ b/src/hooks/useLifecycleActions.tsx @@ -262,6 +262,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, delegateAccountID, submitterLogin, isTrackIntentUser, + formatPhoneNumber, }); refreshSearchAfterReportAction({ currentSearchQueryJSON, diff --git a/src/pages/ReportSubmitToContent.tsx b/src/pages/ReportSubmitToContent.tsx index 320b55790813..272b63f0dcd1 100644 --- a/src/pages/ReportSubmitToContent.tsx +++ b/src/pages/ReportSubmitToContent.tsx @@ -80,7 +80,7 @@ function ReportSubmitToContent({ }: ReportSubmitToContentProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const {translate, localeCompare, dateFnsLocale} = useLocalize(); + const {translate, localeCompare, dateFnsLocale, formatPhoneNumber} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); const isInLandscapeMode = useIsInLandscapeMode(); const {keyboardActiveHeight} = useKeyboardState(); @@ -315,6 +315,7 @@ function ReportSubmitToContent({ managerEmail: trimmed, managerAccountID: resolvedManagerAccountID, isTrackIntentUser, + formatPhoneNumber, onSubmitted: () => { if (currentSearchQueryJSON && !isOffline) { search({ diff --git a/tests/actions/IOUTest/ReportWorkflowTest.ts b/tests/actions/IOUTest/ReportWorkflowTest.ts index 5c920ede37fb..1cbfdff3f827 100644 --- a/tests/actions/IOUTest/ReportWorkflowTest.ts +++ b/tests/actions/IOUTest/ReportWorkflowTest.ts @@ -299,6 +299,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); } return waitForBatchedUpdates(); @@ -414,6 +415,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -537,6 +539,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -645,6 +648,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -754,6 +758,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1076,6 +1081,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); } return waitForBatchedUpdates(); @@ -1355,6 +1361,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); } return waitForBatchedUpdates(); @@ -1531,6 +1538,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); } return waitForBatchedUpdates(); @@ -1606,6 +1614,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1725,6 +1734,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -1789,6 +1799,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -1856,6 +1867,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -1909,6 +1921,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, submitterLogin: submitterEmail, shouldExportToPDF: true, + formatPhoneNumber, }); const pdfNvpKey = `${ONYXKEYS.COLLECTION.NVP_EXPENSIFY_REPORT_PDF_FILENAME}${expenseReport.reportID}`; @@ -1964,6 +1977,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, submitterLogin: submitterEmail, + formatPhoneNumber, }); const pdfNvpKey = `${ONYXKEYS.COLLECTION.NVP_EXPENSIFY_REPORT_PDF_FILENAME}${expenseReport.reportID}`; @@ -2036,6 +2050,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -2129,6 +2144,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateAccountID: undefined, submitterLogin: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -2222,6 +2238,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -2298,6 +2315,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); await waitForBatchedUpdates(); @@ -2370,6 +2388,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, parameters, onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -2441,6 +2460,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); expect(apiWriteSpy).toHaveBeenCalledTimes(1); @@ -2506,6 +2526,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); expect(apiWriteSpy).toHaveBeenCalledTimes(1); @@ -2551,6 +2572,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); const [, , onyxData] = getRequiredWriteCall(apiWriteSpy.mock.calls); @@ -2858,6 +2880,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: DELEGATE_EMAIL, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure @@ -2897,6 +2920,7 @@ describe('actions/IOU/ReportWorkflow', () => { delegateEmail: undefined, delegateAccountID: undefined, isTrackIntentUser: false, + formatPhoneNumber, }); // eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting mock call args to verify optimistic data structure