Skip to content

Commit 0c0664a

Browse files
committed
disallow updating archived invoice
1 parent 9734fbc commit 0c0664a

3 files changed

Lines changed: 63 additions & 12 deletions

File tree

src/components/ReportActionItem/MoneyRequestView.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import useActiveRoute from '@hooks/useActiveRoute';
1717
import useLocalize from '@hooks/useLocalize';
1818
import useNetwork from '@hooks/useNetwork';
1919
import useOnyx from '@hooks/useOnyx';
20+
import useReportIsArchived from '@hooks/useReportIsArchived';
2021
import useResponsiveLayout from '@hooks/useResponsiveLayout';
2122
import useThemeStyles from '@hooks/useThemeStyles';
2223
import useTransactionViolations from '@hooks/useTransactionViolations';
@@ -198,20 +199,21 @@ function MoneyRequestView({allReports, report, policy, shouldShowAnimatedBackgro
198199

199200
const isSettled = isSettledReportUtils(moneyRequestReport?.reportID);
200201
const isCancelled = moneyRequestReport && moneyRequestReport?.isCancelledIOU;
202+
const isChatReportArchived = useReportIsArchived(moneyRequestReport?.chatReportID);
201203

202204
// Flags for allowing or disallowing editing an expense
203205
// Used for non-restricted fields such as: description, category, tag, billable, etc...
204206
const canUserPerformWriteAction = !!canUserPerformWriteActionReportUtils(report) && !readonly;
205-
const canEdit = isMoneyRequestAction(parentReportAction) && canEditMoneyRequest(parentReportAction, transaction) && canUserPerformWriteAction;
207+
const canEdit = isMoneyRequestAction(parentReportAction) && canEditMoneyRequest(parentReportAction, transaction, isChatReportArchived) && canUserPerformWriteAction;
206208

207209
const canEditTaxFields = canEdit && !isDistanceRequest;
208-
const canEditAmount = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.AMOUNT);
209-
const canEditMerchant = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT);
210-
const canEditDate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE);
211-
const canEditReceipt = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT);
212-
const canEditDistance = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE);
213-
const canEditDistanceRate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE);
214-
const canEditReport = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REPORT);
210+
const canEditAmount = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.AMOUNT, undefined, isChatReportArchived);
211+
const canEditMerchant = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT, undefined, isChatReportArchived);
212+
const canEditDate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE, undefined, isChatReportArchived);
213+
const canEditReceipt = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT, undefined, isChatReportArchived);
214+
const canEditDistance = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE, undefined, isChatReportArchived);
215+
const canEditDistanceRate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE, undefined, isChatReportArchived);
216+
const canEditReport = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, isChatReportArchived);
215217

216218
// A flag for verifying that the current report is a sub-report of a expense chat
217219
// if the policy of the report is either Collect or Control, then this report must be tied to expense chat

src/libs/ReportUtils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4031,7 +4031,11 @@ function isWorkspacePayer(memberLogin: string, policy: OnyxEntry<Policy>): boole
40314031
* This is used in conjunction with canEditRestrictedField to control editing of specific fields like amount, currency, created, receipt, and distance.
40324032
* On its own, it only controls allowing/disallowing navigating to the editing pages or showing/hiding the 'Edit' icon on report actions
40334033
*/
4034-
function canEditMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>>, linkedTransaction?: OnyxEntry<Transaction>): boolean {
4034+
function canEditMoneyRequest(
4035+
reportAction: OnyxInputOrEntry<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>>,
4036+
linkedTransaction?: OnyxEntry<Transaction>,
4037+
isChatReportArchived = false,
4038+
): boolean {
40354039
const isDeleted = isDeletedAction(reportAction);
40364040

40374041
if (isDeleted) {
@@ -4072,7 +4076,7 @@ function canEditMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction<typeof
40724076
const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN;
40734077
const isManager = currentUserAccountID === moneyRequestReport?.managerID;
40744078

4075-
if (isInvoiceReport(moneyRequestReport) && isManager) {
4079+
if (isInvoiceReport(moneyRequestReport) && (isManager || isChatReportArchived)) {
40764080
return false;
40774081
}
40784082

@@ -4155,7 +4159,12 @@ function canEditReportPolicy(report: OnyxEntry<Report>, reportPolicy: OnyxEntry<
41554159
* Checks if the current user can edit the provided property of an expense
41564160
*
41574161
*/
4158-
function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>, fieldToEdit: ValueOf<typeof CONST.EDIT_REQUEST_FIELD>, isDeleteAction?: boolean): boolean {
4162+
function canEditFieldOfMoneyRequest(
4163+
reportAction: OnyxInputOrEntry<ReportAction>,
4164+
fieldToEdit: ValueOf<typeof CONST.EDIT_REQUEST_FIELD>,
4165+
isDeleteAction?: boolean,
4166+
isChatReportArchived = false,
4167+
): boolean {
41594168
// A list of fields that cannot be edited by anyone, once an expense has been settled
41604169
const restrictedFields: string[] = [
41614170
CONST.EDIT_REQUEST_FIELD.AMOUNT,
@@ -4168,7 +4177,7 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>
41684177
CONST.EDIT_REQUEST_FIELD.REPORT,
41694178
];
41704179

4171-
if (!isMoneyRequestAction(reportAction) || !canEditMoneyRequest(reportAction)) {
4180+
if (!isMoneyRequestAction(reportAction) || !canEditMoneyRequest(reportAction, undefined, isChatReportArchived)) {
41724181
return false;
41734182
}
41744183

tests/unit/ReportUtilsTest.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
canAddTransaction,
2323
canDeleteReportAction,
2424
canDeleteTransaction,
25+
canEditMoneyRequest,
2526
canEditReportDescription,
2627
canEditRoomVisibility,
2728
canEditWriteCapability,
@@ -1820,6 +1821,45 @@ describe('ReportUtils', () => {
18201821
});
18211822
});
18221823

1824+
describe('canEditMoneyRequest', () => {
1825+
it('it should return false for archived invoice', async () => {
1826+
const invoiceReport: Report = {
1827+
reportID: '1',
1828+
type: CONST.REPORT.TYPE.INVOICE,
1829+
};
1830+
const transaction = createRandomTransaction(22);
1831+
const moneyRequestAction: ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU> = {
1832+
reportActionID: '22',
1833+
actorAccountID: currentUserAccountID,
1834+
actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
1835+
originalMessage: {
1836+
IOUReportID: invoiceReport.reportID,
1837+
IOUTransactionID: transaction.transactionID,
1838+
amount: 530,
1839+
currency: CONST.CURRENCY.USD,
1840+
type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
1841+
},
1842+
message: [
1843+
{
1844+
type: 'COMMENT',
1845+
html: 'USD 5.30 expense',
1846+
text: 'USD 5.30 expense',
1847+
isEdited: false,
1848+
whisperedTo: [],
1849+
isDeletedParentAction: false,
1850+
deleted: '',
1851+
},
1852+
],
1853+
created: '2025-03-05 16:34:27',
1854+
};
1855+
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${invoiceReport.reportID}`, invoiceReport);
1856+
1857+
const canEditRequest = canEditMoneyRequest(moneyRequestAction, transaction, true);
1858+
1859+
expect(canEditRequest).toEqual(false);
1860+
});
1861+
});
1862+
18231863
describe('getChatByParticipants', () => {
18241864
const userAccountID = 1;
18251865
const userAccountID2 = 2;

0 commit comments

Comments
 (0)