From 8f5f090b0972a5c6b428501a43f9feecee8752c5 Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Mon, 15 Dec 2025 21:03:04 +0700 Subject: [PATCH 1/6] Fix - Rejected expense is displayed duplicated in the report --- src/libs/actions/IOU.ts | 1 + tests/actions/IOUTest.ts | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a95955b8f9e6..a263b2ce7d30 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -13664,6 +13664,7 @@ function prepareRejectMoneyRequestData( existingTransactionThreadReportID: childReportID, shouldGenerateTransactionThreadReport: false, }); + createdIOUReportActionID = iouAction.reportActionID; optimisticData.push( { diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 9f0683163a85..1d746f089972 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -10177,6 +10177,57 @@ describe('actions/IOU', () => { ]), ); }); + + it('should the createdIOUReportActionID parameter not be undefined when rejecting an expense to an open report', async () => { + // Mock API.write for this test + const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn()); + + const openReport = { + ...createRandomReport(3, undefined), + type: CONST.REPORT.TYPE.EXPENSE, + ownerAccountID: TEST_USER_ACCOUNT_ID, + managerID: MANAGER_ACCOUNT_ID, + total: 0, + currency: CONST.CURRENCY.USD, + stateNum: CONST.REPORT.STATE_NUM.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, + policyID: policy?.id, + chatReportID: chatReport?.reportID, + }; + + const secondTransaction = { + ...createRandomTransaction(2), + reportID: iouReport?.reportID, + amount, + currency: CONST.CURRENCY.USD, + merchant: 'Test Merchant', + transactionID: '2', + }; + + // Given: An expense report (not IOU) + const expenseReport = {...iouReport, type: CONST.REPORT.TYPE.EXPENSE, total: amount * 2}; + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${openReport.reportID}`, openReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${secondTransaction.transactionID}`, secondTransaction); + await waitForBatchedUpdates(); + + // When: Reject the money request + if (!transaction?.transactionID || !iouReport?.reportID) { + throw new Error('Required transaction or report data is missing'); + } + rejectMoneyRequest(transaction.transactionID, iouReport.reportID, comment, policy); + await waitForBatchedUpdates(); + + // Then: createdIOUReportActionID shouldn't be undefined + expect(writeSpy).toHaveBeenCalledWith( + expect.anything(), + expect.not.objectContaining({ + createdIOUReportActionID: undefined, + }), + expect.anything(), + ); + writeSpy.mockRestore(); + }); }); describe('markRejectViolationAsResolved', () => { From ffb1695f1585a608a225525d8d98c322a7ee8a3a Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Mon, 15 Dec 2025 21:43:36 +0700 Subject: [PATCH 2/6] fix lint --- tests/actions/IOUTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 1d746f089972..b018e54a6267 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -10182,7 +10182,7 @@ describe('actions/IOU', () => { // Mock API.write for this test const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn()); - const openReport = { + const openingReport = { ...createRandomReport(3, undefined), type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: TEST_USER_ACCOUNT_ID, @@ -10207,7 +10207,7 @@ describe('actions/IOU', () => { // Given: An expense report (not IOU) const expenseReport = {...iouReport, type: CONST.REPORT.TYPE.EXPENSE, total: amount * 2}; await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport); - await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${openReport.reportID}`, openReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${openingReport.reportID}`, openingReport); await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${secondTransaction.transactionID}`, secondTransaction); await waitForBatchedUpdates(); From 3a74a7da3e5ce1251c4f41470dfb44c371f19989 Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Mon, 15 Dec 2025 22:09:39 +0700 Subject: [PATCH 3/6] fix lint --- tests/actions/IOUTest.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index b018e54a6267..04b6ab6f374e 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -10180,6 +10180,7 @@ describe('actions/IOU', () => { it('should the createdIOUReportActionID parameter not be undefined when rejecting an expense to an open report', async () => { // Mock API.write for this test + // eslint-disable-next-line rulesdir/no-multiple-api-calls const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn()); const openingReport = { From 884d9382e73c131b2020ef25abee14be3393b6b5 Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Tue, 16 Dec 2025 18:11:35 +0700 Subject: [PATCH 4/6] fix lint --- src/libs/actions/IOU.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e4aaa858ab79..714a31b693a9 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5067,6 +5067,7 @@ function updateMoneyRequestDate({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5168,6 +5169,7 @@ function updateMoneyRequestMerchant( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5362,6 +5364,7 @@ function updateMoneyRequestDistance({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5489,6 +5492,7 @@ function updateMoneyRequestDescription( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5555,6 +5559,7 @@ function updateMoneyRequestDistanceRate({ } let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -8647,6 +8652,7 @@ function updateMoneyRequestAmountAndCurrency({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { From 5b17d006674382e1f5dc1cfd559bedecdcaa88bf Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Tue, 16 Dec 2025 18:12:21 +0700 Subject: [PATCH 5/6] Revert "fix lint" This reverts commit 884d9382e73c131b2020ef25abee14be3393b6b5. --- src/libs/actions/IOU.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 714a31b693a9..e4aaa858ab79 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5067,7 +5067,6 @@ function updateMoneyRequestDate({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5169,7 +5168,6 @@ function updateMoneyRequestMerchant( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5364,7 +5362,6 @@ function updateMoneyRequestDistance({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5492,7 +5489,6 @@ function updateMoneyRequestDescription( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5559,7 +5555,6 @@ function updateMoneyRequestDistanceRate({ } let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -8652,7 +8647,6 @@ function updateMoneyRequestAmountAndCurrency({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; - // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { From 31d907a5af78ea61a2b126dbdd09d816d776464e Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Tue, 16 Dec 2025 18:23:11 +0700 Subject: [PATCH 6/6] fix lint --- src/libs/actions/IOU.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e4aaa858ab79..714a31b693a9 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5067,6 +5067,7 @@ function updateMoneyRequestDate({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5168,6 +5169,7 @@ function updateMoneyRequestMerchant( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5362,6 +5364,7 @@ function updateMoneyRequestDistance({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5489,6 +5492,7 @@ function updateMoneyRequestDescription( const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -5555,6 +5559,7 @@ function updateMoneyRequestDistanceRate({ } let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else { @@ -8647,6 +8652,7 @@ function updateMoneyRequestAmountAndCurrency({ const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; + // eslint-disable-next-line @typescript-eslint/no-deprecated if (isTrackExpenseReport(transactionThreadReport) && isSelfDM(parentReport)) { data = getUpdateTrackExpenseParams(transactionID, transactionThreadReportID, transactionChanges, policy); } else {