Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import useActiveRoute from '@hooks/useActiveRoute';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import useReportIsArchived from '@hooks/useReportIsArchived';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useTransactionViolations from '@hooks/useTransactionViolations';
Expand Down Expand Up @@ -199,20 +200,21 @@ function MoneyRequestView({allReports, report, policy, shouldShowAnimatedBackgro

const isSettled = isSettledReportUtils(moneyRequestReport?.reportID);
const isCancelled = moneyRequestReport && moneyRequestReport?.isCancelledIOU;
const isChatReportArchived = useReportIsArchived(moneyRequestReport?.chatReportID);

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

const canEditTaxFields = canEdit && !isDistanceRequest;
const canEditAmount = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.AMOUNT);
const canEditMerchant = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT);
const canEditDate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE);
const canEditReceipt = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT);
const canEditDistance = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE);
const canEditDistanceRate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE);
const canEditReport = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REPORT);
const canEditAmount = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.AMOUNT, undefined, isChatReportArchived);
const canEditMerchant = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT, undefined, isChatReportArchived);
const canEditDate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE, undefined, isChatReportArchived);
const canEditReceipt = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT, undefined, isChatReportArchived);
const canEditDistance = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE, undefined, isChatReportArchived);
const canEditDistanceRate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE, undefined, isChatReportArchived);
const canEditReport = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REPORT, undefined, isChatReportArchived);

// A flag for verifying that the current report is a sub-report of a expense chat
// if the policy of the report is either Collect or Control, then this report must be tied to expense chat
Expand Down
17 changes: 13 additions & 4 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4031,7 +4031,11 @@ function isWorkspacePayer(memberLogin: string, policy: OnyxEntry<Policy>): boole
* This is used in conjunction with canEditRestrictedField to control editing of specific fields like amount, currency, created, receipt, and distance.
* On its own, it only controls allowing/disallowing navigating to the editing pages or showing/hiding the 'Edit' icon on report actions
*/
function canEditMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>>, linkedTransaction?: OnyxEntry<Transaction>): boolean {
function canEditMoneyRequest(
reportAction: OnyxInputOrEntry<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>>,
linkedTransaction?: OnyxEntry<Transaction>,
isChatReportArchived = false,
): boolean {
const isDeleted = isDeletedAction(reportAction);

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

if (isInvoiceReport(moneyRequestReport) && isManager) {
if (isInvoiceReport(moneyRequestReport) && (isManager || isChatReportArchived)) {
return false;
}

Expand Down Expand Up @@ -4155,7 +4159,12 @@ function canEditReportPolicy(report: OnyxEntry<Report>, reportPolicy: OnyxEntry<
* Checks if the current user can edit the provided property of an expense
*
*/
function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>, fieldToEdit: ValueOf<typeof CONST.EDIT_REQUEST_FIELD>, isDeleteAction?: boolean): boolean {
function canEditFieldOfMoneyRequest(
reportAction: OnyxInputOrEntry<ReportAction>,
fieldToEdit: ValueOf<typeof CONST.EDIT_REQUEST_FIELD>,
isDeleteAction?: boolean,
isChatReportArchived = false,
): boolean {
// A list of fields that cannot be edited by anyone, once an expense has been settled
const restrictedFields: string[] = [
CONST.EDIT_REQUEST_FIELD.AMOUNT,
Expand All @@ -4168,7 +4177,7 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>
CONST.EDIT_REQUEST_FIELD.REPORT,
];

if (!isMoneyRequestAction(reportAction) || !canEditMoneyRequest(reportAction)) {
if (!isMoneyRequestAction(reportAction) || !canEditMoneyRequest(reportAction, undefined, isChatReportArchived)) {
return false;
}

Expand Down
40 changes: 40 additions & 0 deletions tests/unit/ReportUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
canDeleteReportAction,
canDeleteTransaction,
canEditFieldOfMoneyRequest,
canEditMoneyRequest,
canEditReportDescription,
canEditRoomVisibility,
canEditWriteCapability,
Expand Down Expand Up @@ -1905,6 +1906,45 @@ describe('ReportUtils', () => {
});
});

describe('canEditMoneyRequest', () => {
it('it should return false for archived invoice', async () => {
const invoiceReport: Report = {
reportID: '1',
type: CONST.REPORT.TYPE.INVOICE,
};
const transaction = createRandomTransaction(22);
const moneyRequestAction: ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU> = {
reportActionID: '22',
actorAccountID: currentUserAccountID,
actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
originalMessage: {
IOUReportID: invoiceReport.reportID,
IOUTransactionID: transaction.transactionID,
amount: 530,
currency: CONST.CURRENCY.USD,
type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
},
message: [
{
type: 'COMMENT',
html: 'USD 5.30 expense',
text: 'USD 5.30 expense',
isEdited: false,
whisperedTo: [],
isDeletedParentAction: false,
deleted: '',
},
],
created: '2025-03-05 16:34:27',
};
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${invoiceReport.reportID}`, invoiceReport);

const canEditRequest = canEditMoneyRequest(moneyRequestAction, transaction, true);

expect(canEditRequest).toEqual(false);
});
});

describe('getChatByParticipants', () => {
const userAccountID = 1;
const userAccountID2 = 2;
Expand Down