From cf74d73d3086a55f3db60007ae287067a13d66a2 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sun, 31 Aug 2025 18:50:13 +0800 Subject: [PATCH 01/12] fix: Report field shows a blank space and NaN when default title is {report:id} {report:total} --- .../MoneyRequestConfirmationList.tsx | 1 + .../MoneyRequestConfirmationListFooter.tsx | 7 +- src/libs/ReportUtils.ts | 10 +- tests/unit/IOUUtilsTest.ts | 2 +- tests/unit/NextStepUtilsTest.ts | 2 +- tests/unit/ReportUtilsTest.ts | 115 +++++++++++++++++- 6 files changed, 128 insertions(+), 9 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 44bdd353596c..e4f52a09a60f 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1124,6 +1124,7 @@ function MoneyRequestConfirmationList({ currency={currency} didConfirm={!!didConfirm} distance={distance} + iouAmount={amountToBeUsed} formattedAmount={formattedAmount} formattedAmountPerAttendee={formattedAmountPerAttendee} formError={formError} diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index 52a5af5e4c59..f38643c21fcb 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -72,6 +72,9 @@ type MoneyRequestConfirmationListFooterProps = { /** The distance of the transaction */ distance: number; + /** The raw numeric amount of the transaction */ + iouAmount: number; + /** The formatted amount of the transaction */ formattedAmount: string; @@ -240,6 +243,7 @@ function MoneyRequestConfirmationListFooter({ onToggleBillable, policy, policyTags, + iouAmount, policyTagLists, rate, receiptFilename, @@ -309,7 +313,7 @@ function MoneyRequestConfirmationListFooter({ } if (!reportName) { - const optimisticReport = buildOptimisticExpenseReport(reportID, policy?.id, policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, Number(formattedAmount), currency); + const optimisticReport = buildOptimisticExpenseReport(reportID, policy?.id, policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, Number(formattedAmount), iouAmount, currency); reportName = populateOptimisticReportFormula(policy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, policy); } @@ -971,6 +975,7 @@ export default memo( prevProps.currency === nextProps.currency && prevProps.didConfirm === nextProps.didConfirm && prevProps.distance === nextProps.distance && + prevProps.iouAmount === nextProps.iouAmount && prevProps.formattedAmount === nextProps.formattedAmount && prevProps.formError === nextProps.formError && prevProps.hasRoute === nextProps.hasRoute && diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 161c29b653e7..78a70ea0697e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -86,6 +86,7 @@ import {getEnvironment, getEnvironmentURL} from './Environment/Environment'; import type EnvironmentType from './Environment/getEnvironment/types'; import {getMicroSecondOnyxErrorWithTranslationKey, isReceiptError} from './ErrorUtils'; import getAttachmentDetails from './fileDownload/getAttachmentDetails'; +import getBase62ReportID from './getBase62ReportID'; import {isReportMessageAttachment} from './isReportMessageAttachment'; import localeCompareLibs from './LocaleCompare'; import {formatPhoneNumber} from './LocalePhoneNumber'; @@ -5992,7 +5993,8 @@ function populateOptimisticReportFormula(formula: string, report: OptimisticExpe // We don't translate because the server response is always in English .replaceAll(/\{report:type\}/gi, 'Expense Report') .replaceAll(/\{report:startdate\}/gi, createdDate ? format(createdDate, CONST.DATE.FNS_FORMAT_STRING) : '') - .replaceAll(/\{report:total\}/gi, report.total !== undefined ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') + .replaceAll(/\{report:id\}/gi, getBase62ReportID(Number(report.reportID))) + .replaceAll(/\{report:total\}/gi, report.total !== undefined && !Number.isNaN(report.total) ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') .replaceAll(/\{report:currency\}/gi, report.currency ?? '') .replaceAll(/\{report:policyname\}/gi, policy?.name ?? '') .replaceAll(/\{report:workspacename\}/gi, policy?.name ?? '') @@ -6098,6 +6100,7 @@ function buildOptimisticExpenseReport( policyID: string | undefined, payeeAccountID: number, total: number, + iouAmount: number, currency: string, nonReimbursableTotal = 0, parentReportActionID?: string, @@ -6105,6 +6108,7 @@ function buildOptimisticExpenseReport( ): OptimisticExpenseReport { // The amount for Expense reports are stored as negative value in the database const storedTotal = total * -1; + const storedIouAmount = iouAmount * -1; const storedNonReimbursableTotal = nonReimbursableTotal * -1; const report = chatReportID ? getReport(chatReportID, allReports) : undefined; const policyName = getPolicyName({report}); @@ -6126,8 +6130,8 @@ function buildOptimisticExpenseReport( reportName: `${policyName} owes ${formattedTotal}`, stateNum, statusNum, - total: storedTotal, - unheldTotal: storedTotal, + total: storedIouAmount, + unheldTotal: storedIouAmount, nonReimbursableTotal: storedNonReimbursableTotal, unheldNonReimbursableTotal: storedNonReimbursableTotal, participants: { diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index 86da9b2d6ec9..5b70274f353c 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -444,7 +444,7 @@ describe('Check valid amount for IOU/Expense request', () => { }); test('Expense amount should be negative', () => { - const expenseReport = ReportUtils.buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); + const expenseReport = ReportUtils.buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); const expenseTransaction = TransactionUtils.buildOptimisticTransaction({ transactionParams: { amount: 100, diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index c3055ac57ae2..94038e6d6f37 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -38,7 +38,7 @@ describe('libs/NextStepUtils', () => { icon: CONST.NEXT_STEP.ICONS.HOURGLASS, message: [], }; - const report = buildOptimisticExpenseReport('fake-chat-report-id-1', policyID, 1, -500, CONST.CURRENCY.USD) as Report; + const report = buildOptimisticExpenseReport('fake-chat-report-id-1', policyID, 1, -500, 500, CONST.CURRENCY.USD) as Report; beforeAll(() => { const policyCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.POLICY, [policy], (item) => item.id); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 43aac315620c..f1fa7881755c 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -8,6 +8,7 @@ import useReportIsArchived from '@hooks/useReportIsArchived'; import {putOnHold} from '@libs/actions/IOU'; import type {OnboardingTaskLinks} from '@libs/actions/Welcome/OnboardingFlow'; import DateUtils from '@libs/DateUtils'; +import getBase62ReportID from '@libs/getBase62ReportID'; import {translateLocal} from '@libs/Localize'; import {getOriginalMessage, isWhisperAction} from '@libs/ReportActionsUtils'; import { @@ -66,6 +67,7 @@ import { isReportOutstanding, isRootGroupChat, parseReportRouteParams, + populateOptimisticReportFormula, prepareOnboardingOnyxData, requiresAttentionFromCurrentUser, shouldDisableRename, @@ -2078,7 +2080,7 @@ describe('ReportUtils', () => { it('should return canUnholdRequest as true for a held duplicate transaction', async () => { const chatReport: Report = {reportID: '1'}; const reportPreviewReportActionID = '8'; - const expenseReport = buildOptimisticExpenseReport(chatReport.reportID, '123', currentUserAccountID, 122, 'USD', undefined, reportPreviewReportActionID); + const expenseReport = buildOptimisticExpenseReport(chatReport.reportID, '123', currentUserAccountID, 122, 122, 'USD', undefined, reportPreviewReportActionID); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, @@ -2417,7 +2419,7 @@ describe('ReportUtils', () => { }); it('should return true when the report has outstanding violations', async () => { - const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); + const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, @@ -2712,7 +2714,7 @@ describe('ReportUtils', () => { }); it('should return false when the report is the single transaction thread', async () => { - const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); + const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, @@ -5562,6 +5564,113 @@ describe('ReportUtils', () => { expect(reportPreviewAction.childManagerAccountID).toBe(iouReport.managerID); }); }); + + describe('populateOptimisticReportFormula', () => { + const mockPolicy: Policy = { + id: 'test-policy-id', + name: 'Test Policy', + type: CONST.POLICY.TYPE.TEAM, + role: CONST.POLICY.ROLE.ADMIN, + owner: 'test@example.com', + outputCurrency: CONST.CURRENCY.USD, + isPolicyExpenseChatEnabled: true, + autoReporting: true, + autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY, + harvesting: { + enabled: true, + }, + defaultBillable: false, + disabledFields: {}, + fieldList: {}, + customUnits: {}, + areCategoriesEnabled: true, + areTagsEnabled: true, + areDistanceRatesEnabled: true, + areWorkflowsEnabled: true, + areReportFieldsEnabled: true, + areConnectionsEnabled: true, + pendingAction: undefined, + errors: {}, + isLoading: false, + errorFields: {}, + }; + + const mockReport = { + reportID: '123456789', + reportName: 'Test Report', + type: CONST.REPORT.TYPE.EXPENSE, + ownerAccountID: 1, + currency: CONST.CURRENCY.USD, + total: -5000, + lastVisibleActionCreated: '2024-01-15 10:30:00', + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, + chatReportID: 'chat-123', + policyID: 'test-policy-id', + participants: {}, + parentReportID: 'chat-123', + }; + + it('should handle NaN total gracefully', () => { + const reportWithNaNTotal = { + ...mockReport, + total: NaN, + }; + + const result = populateOptimisticReportFormula('{report:total}', reportWithNaNTotal, mockPolicy); + expect(result).toBe('{report:total}'); + }); + + it('should replace {report:total} with formatted amount', () => { + const result = populateOptimisticReportFormula('{report:total}', mockReport, mockPolicy); + expect(result).toBe('$50.00'); + }); + + it('should replace {report:id} with base62 report ID', () => { + const result = populateOptimisticReportFormula('{report:id}', mockReport, mockPolicy); + expect(result).toBe(getBase62ReportID(Number(mockReport.reportID))); + }); + + it('should replace multiple placeholders correctly', () => { + const formula = 'Report {report:id} has total {report:total}'; + const result = populateOptimisticReportFormula(formula, mockReport, mockPolicy); + const expectedId = getBase62ReportID(Number(mockReport.reportID)); + expect(result).toBe(`Report ${expectedId} has total $50.00`); + }); + + it('should handle undefined total gracefully', () => { + const reportWithUndefinedTotal = { + ...mockReport, + total: undefined, + }; + + const result = populateOptimisticReportFormula('{report:total}', reportWithUndefinedTotal, mockPolicy); + expect(result).toBe('{report:total}'); + }); + + it('should return original formula when result is empty after replacements', () => { + const formula = '{report:total}'; + const reportWithNaNTotal = { + ...mockReport, + total: NaN, + }; + + const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); + expect(result).toBe('{report:total}'); + }); + + it('should handle complex formula with multiple placeholders and some invalid values', () => { + const formula = 'ID: {report:id}, Total: {report:total}, Type: {report:type}'; + const reportWithNaNTotal = { + ...mockReport, + total: NaN, + }; + + const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); + const expectedId = getBase62ReportID(Number(mockReport.reportID)); + expect(result).toBe(`ID: ${expectedId}, Total: , Type: Expense Report`); + }); + }); describe('canSeeDefaultRoom', () => { it('should return true if report is archived room ', () => { const betas = [CONST.BETAS.DEFAULT_ROOMS]; From 19d50be0103503525943a0279f3559694f643d24 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sun, 31 Aug 2025 19:05:35 +0800 Subject: [PATCH 02/12] fix: refactor --- src/components/MoneyRequestConfirmationListFooter.tsx | 2 +- src/libs/ReportUtils.ts | 9 +++------ tests/unit/IOUUtilsTest.ts | 2 +- tests/unit/NextStepUtilsTest.ts | 2 +- tests/unit/ReportUtilsTest.ts | 6 +++--- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index f38643c21fcb..b73ec18d1c15 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -313,7 +313,7 @@ function MoneyRequestConfirmationListFooter({ } if (!reportName) { - const optimisticReport = buildOptimisticExpenseReport(reportID, policy?.id, policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, Number(formattedAmount), iouAmount, currency); + const optimisticReport = buildOptimisticExpenseReport(reportID, policy?.id, policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, iouAmount ?? transaction?.amount ?? 0, currency); reportName = populateOptimisticReportFormula(policy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, policy); } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 78a70ea0697e..a65d3d1ff4c9 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6099,16 +6099,13 @@ function buildOptimisticExpenseReport( chatReportID: string | undefined, policyID: string | undefined, payeeAccountID: number, - total: number, iouAmount: number, currency: string, nonReimbursableTotal = 0, parentReportActionID?: string, optimisticIOUReportID?: string, ): OptimisticExpenseReport { - // The amount for Expense reports are stored as negative value in the database - const storedTotal = total * -1; - const storedIouAmount = iouAmount * -1; + const storedTotal = iouAmount * -1; const storedNonReimbursableTotal = nonReimbursableTotal * -1; const report = chatReportID ? getReport(chatReportID, allReports) : undefined; const policyName = getPolicyName({report}); @@ -6130,8 +6127,8 @@ function buildOptimisticExpenseReport( reportName: `${policyName} owes ${formattedTotal}`, stateNum, statusNum, - total: storedIouAmount, - unheldTotal: storedIouAmount, + total: storedTotal, + unheldTotal: storedTotal, nonReimbursableTotal: storedNonReimbursableTotal, unheldNonReimbursableTotal: storedNonReimbursableTotal, participants: { diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index 5b70274f353c..86da9b2d6ec9 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -444,7 +444,7 @@ describe('Check valid amount for IOU/Expense request', () => { }); test('Expense amount should be negative', () => { - const expenseReport = ReportUtils.buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); + const expenseReport = ReportUtils.buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); const expenseTransaction = TransactionUtils.buildOptimisticTransaction({ transactionParams: { amount: 100, diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index 94038e6d6f37..c3055ac57ae2 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -38,7 +38,7 @@ describe('libs/NextStepUtils', () => { icon: CONST.NEXT_STEP.ICONS.HOURGLASS, message: [], }; - const report = buildOptimisticExpenseReport('fake-chat-report-id-1', policyID, 1, -500, 500, CONST.CURRENCY.USD) as Report; + const report = buildOptimisticExpenseReport('fake-chat-report-id-1', policyID, 1, -500, CONST.CURRENCY.USD) as Report; beforeAll(() => { const policyCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.POLICY, [policy], (item) => item.id); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index f1fa7881755c..34a03472e397 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -2080,7 +2080,7 @@ describe('ReportUtils', () => { it('should return canUnholdRequest as true for a held duplicate transaction', async () => { const chatReport: Report = {reportID: '1'}; const reportPreviewReportActionID = '8'; - const expenseReport = buildOptimisticExpenseReport(chatReport.reportID, '123', currentUserAccountID, 122, 122, 'USD', undefined, reportPreviewReportActionID); + const expenseReport = buildOptimisticExpenseReport(chatReport.reportID, '123', currentUserAccountID, 122, 'USD', undefined, reportPreviewReportActionID); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, @@ -2419,7 +2419,7 @@ describe('ReportUtils', () => { }); it('should return true when the report has outstanding violations', async () => { - const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); + const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, @@ -2714,7 +2714,7 @@ describe('ReportUtils', () => { }); it('should return false when the report is the single transaction thread', async () => { - const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 100, 122, 'USD'); + const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, From 6c322eeac6d694f61a3b4e81e32ce1a0dac264f4 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sun, 31 Aug 2025 19:12:31 +0800 Subject: [PATCH 03/12] chore: add code comment --- src/libs/ReportUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a65d3d1ff4c9..a0d145876548 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6105,6 +6105,7 @@ function buildOptimisticExpenseReport( parentReportActionID?: string, optimisticIOUReportID?: string, ): OptimisticExpenseReport { + // The amount for Expense reports are stored as negative value in the database const storedTotal = iouAmount * -1; const storedNonReimbursableTotal = nonReimbursableTotal * -1; const report = chatReportID ? getReport(chatReportID, allReports) : undefined; From a94ba6a0beb5bdcfb6eec5a8cc1aaca1ef335d2d Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sun, 31 Aug 2025 19:28:46 +0800 Subject: [PATCH 04/12] fix: naming --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a0d145876548..821e7f6e73f4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6099,14 +6099,14 @@ function buildOptimisticExpenseReport( chatReportID: string | undefined, policyID: string | undefined, payeeAccountID: number, - iouAmount: number, + total: number, currency: string, nonReimbursableTotal = 0, parentReportActionID?: string, optimisticIOUReportID?: string, ): OptimisticExpenseReport { // The amount for Expense reports are stored as negative value in the database - const storedTotal = iouAmount * -1; + const storedTotal = total * -1; const storedNonReimbursableTotal = nonReimbursableTotal * -1; const report = chatReportID ? getReport(chatReportID, allReports) : undefined; const policyName = getPolicyName({report}); From 3c8bc97c13da31067f3cb6dc37e7493d75d45f00 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Mon, 8 Sep 2025 23:48:24 +0800 Subject: [PATCH 05/12] fix: address comments --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 5f905e0f163f..055f0a263d49 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5994,7 +5994,7 @@ function populateOptimisticReportFormula(formula: string, report: OptimisticExpe .replaceAll(/\{report:type\}/gi, 'Expense Report') .replaceAll(/\{report:startdate\}/gi, createdDate ? format(createdDate, CONST.DATE.FNS_FORMAT_STRING) : '') .replaceAll(/\{report:id\}/gi, getBase62ReportID(Number(report.reportID))) - .replaceAll(/\{report:total\}/gi, report.total !== undefined && !Number.isNaN(report.total) ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') + .replaceAll(/\{report:total\}/gi, report.total && !Number.isNaN(report.total) ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') .replaceAll(/\{report:currency\}/gi, report.currency ?? '') .replaceAll(/\{report:policyname\}/gi, policy?.name ?? '') .replaceAll(/\{report:workspacename\}/gi, policy?.name ?? '') From 7cd076f822bbc502f84194f3b6c4512a6401173a Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Wed, 10 Sep 2025 23:46:18 +0800 Subject: [PATCH 06/12] chore: add translations --- src/languages/de.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/languages/fr.ts | 1 + src/languages/it.ts | 1 + src/languages/ja.ts | 1 + src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 1 + src/languages/zh-hans.ts | 1 + src/libs/ReportUtils.ts | 8 +++++++- 11 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 06d49c112248..ce461e78dd2f 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -1311,6 +1311,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Keine nicht gemeldeten Ausgaben', emptyStateUnreportedExpenseSubtitle: 'Es sieht so aus, als hätten Sie keine nicht gemeldeten Ausgaben. Versuchen Sie, unten eine zu erstellen.', addUnreportedExpenseConfirm: 'Zum Bericht hinzufügen', + newReport: 'Neuer Bericht', explainHold: 'Erklären Sie, warum Sie diese Ausgabe zurückhalten.', retracted: 'zurückgezogen', retract: 'Zurückziehen', diff --git a/src/languages/en.ts b/src/languages/en.ts index f31b72030a89..5063df6f72b4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1295,6 +1295,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'No unreported expenses', emptyStateUnreportedExpenseSubtitle: 'Looks like you don’t have any unreported expenses. Try creating one below.', addUnreportedExpenseConfirm: 'Add to report', + newReport: 'New report', explainHold: "Explain why you're holding this expense.", retracted: 'retracted', retract: 'Retract', diff --git a/src/languages/es.ts b/src/languages/es.ts index 2037c8624065..5471729b4787 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1290,6 +1290,7 @@ const translations = { addUnreportedExpenseConfirm: 'Añadir al informe', heldExpense: 'retuvo este gasto', unheldExpense: 'desbloqueó este gasto', + newReport: 'Nuevo informe', explainHold: 'Explica la razón para retener esta solicitud.', retract: 'Retractar', reopened: 'reabrir', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 912a0742e4bc..bea20bbdcd65 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -1314,6 +1314,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Aucune dépense non déclarée', emptyStateUnreportedExpenseSubtitle: "Il semble que vous n'ayez aucune dépense non déclarée. Essayez d'en créer une ci-dessous.", addUnreportedExpenseConfirm: 'Ajouter au rapport', + newReport: 'Nouveau rapport', explainHold: 'Expliquez pourquoi vous retenez cette dépense.', retracted: 'retraité', retract: 'Retirer', diff --git a/src/languages/it.ts b/src/languages/it.ts index 468560516745..dad794e5c16b 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -1307,6 +1307,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Nessuna spesa non segnalata', emptyStateUnreportedExpenseSubtitle: 'Sembra che non hai spese non segnalate. Prova a crearne una qui sotto.', addUnreportedExpenseConfirm: 'Aggiungi al report', + newReport: 'Nuovo rapporto', explainHold: 'Spiega perché stai trattenendo questa spesa.', retracted: 'retratato', retract: 'Ritirare', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index d1f3ec4e340c..9610d75f20c3 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -1308,6 +1308,7 @@ const translations = { emptyStateUnreportedExpenseTitle: '未報告の経費はありません', emptyStateUnreportedExpenseSubtitle: '未報告の経費はないようです。以下で新しく作成してみてください。', addUnreportedExpenseConfirm: 'レポートに追加', + newReport: '新しいレポート', explainHold: 'この経費を保留している理由を説明してください。', retracted: '撤回されました', retract: '取り消す', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 64a88b05ec66..15f79848fac6 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -1309,6 +1309,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Geen niet-gerapporteerde uitgaven', emptyStateUnreportedExpenseSubtitle: 'Het lijkt erop dat je geen niet-gerapporteerde uitgaven hebt. Probeer er hieronder een aan te maken.', addUnreportedExpenseConfirm: 'Toevoegen aan rapport', + newReport: 'Nieuw rapport', explainHold: 'Leg uit waarom je deze uitgave vasthoudt.', retracted: 'ingetrokken', retract: 'Intrekken', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 8e736d50b9b7..d0dfdd09802b 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -1306,6 +1306,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Brak niezgłoszonych wydatków', emptyStateUnreportedExpenseSubtitle: 'Wygląda na to, że nie masz żadnych niezgłoszonych wydatków. Spróbuj utworzyć jeden poniżej.', addUnreportedExpenseConfirm: 'Dodaj do raportu', + newReport: 'Nowy raport', explainHold: 'Wyjaśnij, dlaczego wstrzymujesz ten wydatek.', retracted: 'wycofany', retract: 'Wycofać', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index b0a547a67863..59df5a1487ff 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -1307,6 +1307,7 @@ const translations = { emptyStateUnreportedExpenseTitle: 'Nenhuma despesa não relatada', emptyStateUnreportedExpenseSubtitle: 'Parece que você não tem nenhuma despesa não relatada. Tente criar uma abaixo.', addUnreportedExpenseConfirm: 'Adicionar ao relatório', + newReport: 'Novo relatório', explainHold: 'Explique por que você está retendo esta despesa.', retracted: 'retraído', retract: 'Retrair', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 6ecf2ac23e34..5e6cf574590c 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -1293,6 +1293,7 @@ const translations = { emptyStateUnreportedExpenseTitle: '没有未报告的费用', emptyStateUnreportedExpenseSubtitle: '看起来您没有未报告的费用。请尝试在下面创建一个。', addUnreportedExpenseConfirm: '添加到报告', + newReport: '新报告', explainHold: '请解释您为何保留此费用。', retracted: '撤回', retract: '撤回', diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4f25f42005e7..4a6c7d804d26 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6022,13 +6022,19 @@ function getHumanReadableStatus(statusNum: number): string { * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport, policy: OnyxEntry): string { + // If the report is not finalized yet (not having total value), we should use 'New report' as the report title + if (!report.total) { + return translateLocal('iou.newReport'); + } + const createdDate = report.lastVisibleActionCreated ? new Date(report.lastVisibleActionCreated) : undefined; + const result = formula // We don't translate because the server response is always in English .replaceAll(/\{report:type\}/gi, 'Expense Report') .replaceAll(/\{report:startdate\}/gi, createdDate ? format(createdDate, CONST.DATE.FNS_FORMAT_STRING) : '') .replaceAll(/\{report:id\}/gi, getBase62ReportID(Number(report.reportID))) - .replaceAll(/\{report:total\}/gi, report.total && !Number.isNaN(report.total) ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') + .replaceAll(/\{report:total\}/gi, report.total !== undefined && !Number.isNaN(report.total) ? convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') .replaceAll(/\{report:currency\}/gi, report.currency ?? '') .replaceAll(/\{report:policyname\}/gi, policy?.name ?? '') .replaceAll(/\{report:workspacename\}/gi, policy?.name ?? '') From a26ad28691083b10060df6969738416dcc934ec9 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Thu, 11 Sep 2025 00:10:38 +0800 Subject: [PATCH 07/12] fix: test --- tests/unit/ReportUtilsTest.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index bb00dba5389c..0a455cc32fd2 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -5633,7 +5633,7 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula('{report:total}', reportWithNaNTotal, mockPolicy); - expect(result).toBe('{report:total}'); + expect(result).toBe('New report'); }); it('should replace {report:total} with formatted amount', () => { @@ -5660,10 +5660,10 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula('{report:total}', reportWithUndefinedTotal, mockPolicy); - expect(result).toBe('{report:total}'); + expect(result).toBe('New report'); }); - it('should return original formula when result is empty after replacements', () => { + it('should return "New report" when result is empty after replacements', () => { const formula = '{report:total}'; const reportWithNaNTotal = { ...mockReport, @@ -5671,7 +5671,7 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); - expect(result).toBe('{report:total}'); + expect(result).toBe('New report'); }); it('should handle complex formula with multiple placeholders and some invalid values', () => { @@ -5682,8 +5682,17 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); - const expectedId = getBase62ReportID(Number(mockReport.reportID)); - expect(result).toBe(`ID: ${expectedId}, Total: , Type: Expense Report`); + expect(result).toBe('New report'); + }); + + it('should handle missing total gracefully', () => { + const reportWithMissingTotal = { + ...mockReport, + total: undefined, + }; + + const result = populateOptimisticReportFormula('{report:total}', reportWithMissingTotal, mockPolicy); + expect(result).toBe('New report'); }); }); describe('canSeeDefaultRoom', () => { From d24eca23189ad0f300212c169a74c4b0a52050c0 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sat, 13 Sep 2025 18:06:59 +0800 Subject: [PATCH 08/12] feat: handling new report case --- .../MoneyRequestConfirmationListFooter.tsx | 2 +- src/libs/ReportUtils.ts | 6 +++--- tests/unit/ReportUtilsTest.ts | 21 +++++-------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index 0d09a2984da5..1c3292b57a6b 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -342,7 +342,7 @@ function MoneyRequestConfirmationListFooter({ currency, ); selectedReportID = !selectedReportID ? optimisticReport.reportID : selectedReportID; - reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy); + reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy, true); } // When creating an expense in an individual report, the report field becomes read-only diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 44d885abbe76..61ec70ea0506 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6055,9 +6055,9 @@ function getHumanReadableStatus(statusNum: number): string { * If after all replacements the formula is empty, the original formula is returned. * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ -function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport, policy: OnyxEntry): string { - // If the report is not finalized yet (not having total value), we should use 'New report' as the report title - if (!report.total) { +function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry, isMoneyrequestConfirmation = false): string { + // If this is a newly created report and it is from money request confirmation, we should use 'New report' as the report title + if (!report.parentReportActionID && isMoneyrequestConfirmation) { return translateLocal('iou.newReport'); } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 0a455cc32fd2..514183e91793 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -5633,7 +5633,7 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula('{report:total}', reportWithNaNTotal, mockPolicy); - expect(result).toBe('New report'); + expect(result).toBe('{report:total}'); }); it('should replace {report:total} with formatted amount', () => { @@ -5660,18 +5660,7 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula('{report:total}', reportWithUndefinedTotal, mockPolicy); - expect(result).toBe('New report'); - }); - - it('should return "New report" when result is empty after replacements', () => { - const formula = '{report:total}'; - const reportWithNaNTotal = { - ...mockReport, - total: NaN, - }; - - const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); - expect(result).toBe('New report'); + expect(result).toBe('{report:total}'); }); it('should handle complex formula with multiple placeholders and some invalid values', () => { @@ -5680,9 +5669,9 @@ describe('ReportUtils', () => { ...mockReport, total: NaN, }; - + const expectedId = getBase62ReportID(Number(mockReport.reportID)); const result = populateOptimisticReportFormula(formula, reportWithNaNTotal, mockPolicy); - expect(result).toBe('New report'); + expect(result).toBe(`ID: ${expectedId}, Total: , Type: Expense Report`); }); it('should handle missing total gracefully', () => { @@ -5692,7 +5681,7 @@ describe('ReportUtils', () => { }; const result = populateOptimisticReportFormula('{report:total}', reportWithMissingTotal, mockPolicy); - expect(result).toBe('New report'); + expect(result).toBe('{report:total}'); }); }); describe('canSeeDefaultRoom', () => { From f5ab79d9b55202ba6ef6ee72a418a63f50cc025b Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sat, 13 Sep 2025 18:22:57 +0800 Subject: [PATCH 09/12] fix: spell --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 61ec70ea0506..4e0f3bbddaa1 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6055,9 +6055,9 @@ function getHumanReadableStatus(statusNum: number): string { * If after all replacements the formula is empty, the original formula is returned. * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ -function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry, isMoneyrequestConfirmation = false): string { +function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry, isMoneyRequestConfirmation = false): string { // If this is a newly created report and it is from money request confirmation, we should use 'New report' as the report title - if (!report.parentReportActionID && isMoneyrequestConfirmation) { + if (!report.parentReportActionID && isMoneyRequestConfirmation) { return translateLocal('iou.newReport'); } From f5634732c09b9ff1f15105c615eb2aa8c9110366 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Sat, 13 Sep 2025 19:04:07 +0800 Subject: [PATCH 10/12] fix: logic --- src/components/MoneyRequestConfirmationListFooter.tsx | 2 +- src/libs/ReportUtils.ts | 6 +++--- tests/unit/ReportUtilsTest.ts | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index 1c3292b57a6b..0d09a2984da5 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -342,7 +342,7 @@ function MoneyRequestConfirmationListFooter({ currency, ); selectedReportID = !selectedReportID ? optimisticReport.reportID : selectedReportID; - reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy, true); + reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy); } // When creating an expense in an individual report, the report field becomes read-only diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4e0f3bbddaa1..362cf2d07a0b 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6055,9 +6055,9 @@ function getHumanReadableStatus(statusNum: number): string { * If after all replacements the formula is empty, the original formula is returned. * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ -function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry, isMoneyRequestConfirmation = false): string { - // If this is a newly created report and it is from money request confirmation, we should use 'New report' as the report title - if (!report.parentReportActionID && isMoneyRequestConfirmation) { +function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry): string { + // If this is a newly created report, we should use 'New report' as the report title + if (!report.parentReportActionID) { return translateLocal('iou.newReport'); } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 514183e91793..ef8f3ead0413 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -5613,6 +5613,7 @@ describe('ReportUtils', () => { const mockReport = { reportID: '123456789', reportName: 'Test Report', + parentReportActionID: '9876543210', type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: 1, currency: CONST.CURRENCY.USD, From f07593820b33c638aa9804db06d8b44b516ecf25 Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Tue, 16 Sep 2025 11:49:22 +0800 Subject: [PATCH 11/12] chore: only show New Report on confirmation footer --- src/components/MoneyRequestConfirmationListFooter.tsx | 2 +- src/libs/ReportUtils.ts | 6 +++--- tests/unit/ReportUtilsTest.ts | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index 182210350d78..6dd00c0c8539 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -343,7 +343,7 @@ function MoneyRequestConfirmationListFooter({ currency, ); selectedReportID = !selectedReportID ? optimisticReport.reportID : selectedReportID; - reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy); + reportName = populateOptimisticReportFormula(selectedPolicy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, selectedPolicy, true); } // When creating an expense in an individual report, the report field becomes read-only diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 9e66547e93ed..a10ee2a132c0 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6124,9 +6124,9 @@ function getHumanReadableStatus(statusNum: number): string { * If after all replacements the formula is empty, the original formula is returned. * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ -function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry): string { - // If this is a newly created report, we should use 'New report' as the report title - if (!report.parentReportActionID) { +function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport | OptimisticNewReport, policy: OnyxEntry, isMoneyRequestConfirmation = false): string { + // If this is a newly created report and it is from money request confirmation, we should use 'New report' as the report title + if (!report.parentReportActionID && isMoneyRequestConfirmation) { return translateLocal('iou.newReport'); } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index ef8f3ead0413..514183e91793 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -5613,7 +5613,6 @@ describe('ReportUtils', () => { const mockReport = { reportID: '123456789', reportName: 'Test Report', - parentReportActionID: '9876543210', type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: 1, currency: CONST.CURRENCY.USD, From 5758e72f00644130ec36096d2abc9679c5be943a Mon Sep 17 00:00:00 2001 From: lorretheboy Date: Thu, 18 Sep 2025 02:31:46 +0800 Subject: [PATCH 12/12] fix: naming --- src/components/MoneyRequestConfirmationList.tsx | 2 +- src/components/MoneyRequestConfirmationListFooter.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 1462bf3bd756..4d81084a2555 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1129,7 +1129,7 @@ function MoneyRequestConfirmationList({ currency={currency} didConfirm={!!didConfirm} distance={distance} - iouAmount={amountToBeUsed} + rawAmount={amountToBeUsed} formattedAmount={formattedAmount} formattedAmountPerAttendee={formattedAmountPerAttendee} formError={formError} diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index a15801eb5611..65fbf24a3638 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -77,7 +77,7 @@ type MoneyRequestConfirmationListFooterProps = { distance: number; /** The raw numeric amount of the transaction */ - iouAmount: number; + rawAmount: number; /** The formatted amount of the transaction */ formattedAmount: string; @@ -247,7 +247,7 @@ function MoneyRequestConfirmationListFooter({ onToggleBillable, policy, policyTags, - iouAmount, + rawAmount, policyTagLists, rate, receiptFilename, @@ -343,7 +343,7 @@ function MoneyRequestConfirmationListFooter({ reportID, selectedPolicy?.id, selectedPolicy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, - iouAmount ?? transaction?.amount ?? 0, + rawAmount ?? transaction?.amount ?? 0, currency, ); selectedReportID = !selectedReportID ? optimisticReport.reportID : selectedReportID; @@ -1026,7 +1026,7 @@ export default memo( prevProps.currency === nextProps.currency && prevProps.didConfirm === nextProps.didConfirm && prevProps.distance === nextProps.distance && - prevProps.iouAmount === nextProps.iouAmount && + prevProps.rawAmount === nextProps.rawAmount && prevProps.formattedAmount === nextProps.formattedAmount && prevProps.formError === nextProps.formError && prevProps.hasRoute === nextProps.hasRoute &&