From a451af95bcbe91aa7185b95d9ece54341451b7e6 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 20 Aug 2025 17:50:36 +0700 Subject: [PATCH 1/4] fix: report field is not editable for invoice/track expense --- src/libs/ReportUtils.ts | 2 +- tests/unit/canEditFieldOfMoneyRequestTest.ts | 29 ++++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 17567d87c074..156aa5e57f9f 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4300,7 +4300,7 @@ function canEditFieldOfMoneyRequest( } if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.REPORT) { - if (!isReportOutstanding(moneyRequestReport, moneyRequestReport.policyID)) { + if (!isReportOutstanding(moneyRequestReport, moneyRequestReport.policyID) && isExpenseReport(moneyRequestReport)) { return false; } diff --git a/tests/unit/canEditFieldOfMoneyRequestTest.ts b/tests/unit/canEditFieldOfMoneyRequestTest.ts index 6929f224074c..60fdfcd2a90e 100644 --- a/tests/unit/canEditFieldOfMoneyRequestTest.ts +++ b/tests/unit/canEditFieldOfMoneyRequestTest.ts @@ -103,22 +103,14 @@ describe('canEditFieldOfMoneyRequest', () => { return waitForBatchedUpdates(); }); - it('should return false for invoice report action if it is not outstanding report', async () => { + // Then the user should be able to move the invoice to the outstanding expense report + it('should return true for invoice report action given that there is a minimum of one outstanding report', async () => { const outstandingReportsByPolicyID = await OnyxUtils.get(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID); const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); - expect(canEditReportField).toBe(false); - }); - - it('should return true for invoice report action when there are outstanding reports', async () => { - await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${IOUReportID}`, outstandingExpenseReport); - await waitForBatchedUpdates(); - const outstandingReportsByPolicyID = await OnyxUtils.get(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID); - - const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); - expect(canEditReportField).toBe(true); }); + }); describe('type is expense', () => { @@ -260,6 +252,21 @@ describe('canEditFieldOfMoneyRequest', () => { // Then they should not be able to move the expense since there's only one outstanding report expect(canEditReportField).toBe(false); }); + + it('should return false when the expense report is not outstanding report', async () => { + // Given that there are multiple outstanding expense reports in the same policy + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${IOUReportID}`, {...expenseReport, stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.APPROVED}); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${EXPENSE_OUTSTANDING_REPORT_1_ID}`, outstandingExpenseReport1); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${EXPENSE_OUTSTANDING_REPORT_2_ID}`, outstandingExpenseReport2); + await waitForBatchedUpdates(); + const outstandingReportsByPolicyID = await OnyxUtils.get(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID); + + // When the submitter tries to move an expense between reports + const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); + + // Then they should be able to move the expense since there are multiple outstanding expense reports + expect(canEditReportField).toBe(false); + }); }); }); }); From 995076fb0683da2d399bad3fb7e245ee44f2dbe6 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 20 Aug 2025 17:57:23 +0700 Subject: [PATCH 2/4] fix prettier --- tests/unit/canEditFieldOfMoneyRequestTest.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/canEditFieldOfMoneyRequestTest.ts b/tests/unit/canEditFieldOfMoneyRequestTest.ts index 60fdfcd2a90e..0908d88b59e2 100644 --- a/tests/unit/canEditFieldOfMoneyRequestTest.ts +++ b/tests/unit/canEditFieldOfMoneyRequestTest.ts @@ -110,7 +110,6 @@ describe('canEditFieldOfMoneyRequest', () => { const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); expect(canEditReportField).toBe(true); }); - }); describe('type is expense', () => { From 07b911edee8904216892fa6dc553df8c53bbc0de Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 20 Aug 2025 21:09:12 +0700 Subject: [PATCH 3/4] only apply for track expense --- tests/unit/canEditFieldOfMoneyRequestTest.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/unit/canEditFieldOfMoneyRequestTest.ts b/tests/unit/canEditFieldOfMoneyRequestTest.ts index 0908d88b59e2..dd684124ff5c 100644 --- a/tests/unit/canEditFieldOfMoneyRequestTest.ts +++ b/tests/unit/canEditFieldOfMoneyRequestTest.ts @@ -103,11 +103,20 @@ describe('canEditFieldOfMoneyRequest', () => { return waitForBatchedUpdates(); }); - // Then the user should be able to move the invoice to the outstanding expense report - it('should return true for invoice report action given that there is a minimum of one outstanding report', async () => { + it('should return false for invoice report action if it is not outstanding report', async () => { const outstandingReportsByPolicyID = await OnyxUtils.get(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID); const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); + expect(canEditReportField).toBe(false); + }); + + it('should return true for invoice report action when there are outstanding reports', async () => { + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${IOUReportID}`, outstandingExpenseReport); + await waitForBatchedUpdates(); + const outstandingReportsByPolicyID = await OnyxUtils.get(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID); + + const canEditReportField = canEditFieldOfMoneyRequest(reportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, undefined, outstandingReportsByPolicyID); + expect(canEditReportField).toBe(true); }); }); From fab7cf833b77a2cff605bd374c9aeb5eabe05a74 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 20 Aug 2025 22:11:36 +0700 Subject: [PATCH 4/4] push unreport expense check --- src/libs/ReportUtils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 156aa5e57f9f..9b4ab95b158d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4300,7 +4300,10 @@ function canEditFieldOfMoneyRequest( } if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.REPORT) { - if (!isReportOutstanding(moneyRequestReport, moneyRequestReport.policyID) && isExpenseReport(moneyRequestReport)) { + // Unreported transaction from OldDot can have the reportID as an empty string + const isUnreportedExpense = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID; + + if (!isReportOutstanding(moneyRequestReport, moneyRequestReport.policyID) && !isUnreportedExpense) { return false; } @@ -4310,9 +4313,6 @@ function canEditFieldOfMoneyRequest( } const isOwner = moneyRequestReport?.ownerAccountID === currentUserAccountID; - // Unreported transaction from OldDot can have the reportID as an empty string - const isUnreportedExpense = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID; - if (isInvoiceReport(moneyRequestReport) && !isUnreportedExpense) { return ( getOutstandingReportsForUser(