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
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,14 @@ import {
hasNonReimbursableTransactions as hasNonReimbursableTransactionsReportUtils,
hasOnlyHeldExpenses as hasOnlyHeldExpensesReportUtils,
hasOnlyTransactionsWithPendingRoutes as hasOnlyTransactionsWithPendingRoutesReportUtils,
hasReportBeenReopened as hasReportBeenReopenedUtils,
hasReportBeenRetracted as hasReportBeenRetractedUtils,
hasUpdatedTotal,
isInvoiceReport as isInvoiceReportUtils,
isInvoiceRoom as isInvoiceRoomReportUtils,
isPolicyExpenseChat as isPolicyExpenseChatReportUtils,
isReportApproved,
isReportOwner,
isSettled,
isTripRoom as isTripRoomReportUtils,
isWaitingForSubmissionFromCurrentUser as isWaitingForSubmissionFromCurrentUserReportUtils,
Expand Down Expand Up @@ -182,10 +185,18 @@ function MoneyRequestReportPreviewContent({
const hasReceipts = transactionsWithReceipts.length > 0;
const isScanning = hasReceipts && areAllRequestsBeingSmartScanned;

// The submit button should be success green color only if the user is submitter and the policy does not have Scheduled Submit turned on
const isWaitingForSubmissionFromCurrentUser = useMemo(() => isWaitingForSubmissionFromCurrentUserReportUtils(chatReport, policy), [chatReport, policy]);
const {isDelegateAccessRestricted, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext);
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {canBeMissing: true});

const hasReportBeenRetracted = hasReportBeenReopenedUtils(iouReport, reportActions) || hasReportBeenRetractedUtils(iouReport, reportActions);

// The submit button should be success green color only if the user is submitter and the policy does not have Scheduled Submit turned on
// Or if the report has been reopened or retracted
const isWaitingForSubmissionFromCurrentUser = useMemo(() => {
const isOwnAndReportHasBeenRetracted = isReportOwner(iouReport) && hasReportBeenRetracted;
return isOwnAndReportHasBeenRetracted || isWaitingForSubmissionFromCurrentUserReportUtils(chatReport, policy);
}, [chatReport, policy, hasReportBeenRetracted, iouReport]);

const confirmPayment = useCallback(
(type: PaymentMethodType | undefined, payAsBusiness?: boolean) => {
if (!type) {
Expand Down
2 changes: 2 additions & 0 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ function validateReportDraftProperty(key: keyof Report | keyof ReportNameValuePa
case 'hasParentAccess':
case 'isDeletedParentAction':
case 'isWaitingOnBankAccount':
case 'hasReportBeenRetracted':
case 'isCancelledIOU':
case 'hasReportBeenReopened':
case 'isExportedToIntegration':
Expand Down Expand Up @@ -626,6 +627,7 @@ function validateReportDraftProperty(key: keyof Report | keyof ReportNameValuePa
unheldNonReimbursableTotal: CONST.RED_BRICK_ROAD_PENDING_ACTION,
isWaitingOnBankAccount: CONST.RED_BRICK_ROAD_PENDING_ACTION,
isCancelledIOU: CONST.RED_BRICK_ROAD_PENDING_ACTION,
hasReportBeenRetracted: CONST.RED_BRICK_ROAD_PENDING_ACTION,
hasReportBeenReopened: CONST.RED_BRICK_ROAD_PENDING_ACTION,
isExportedToIntegration: CONST.RED_BRICK_ROAD_PENDING_ACTION,
hasExportError: CONST.RED_BRICK_ROAD_PENDING_ACTION,
Expand Down
5 changes: 5 additions & 0 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,10 @@ function isReopenedAction(reportAction: OnyxEntry<ReportAction>): reportAction i
return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.REOPENED);
}

function isRetractedAction(reportAction: OnyxEntry<ReportAction>): reportAction is ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.RETRACTED> {
return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.RETRACTED);
}

function isRoomChangeLogAction(reportAction: OnyxEntry<ReportAction>): reportAction is ReportAction<ValueOf<typeof CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG>> {
return reportAction?.actionName ? ROOM_CHANGE_LOG_ARRAY.has(reportAction.actionName) : false;
}
Expand Down Expand Up @@ -3139,6 +3143,7 @@ export {
getRetractedMessage,
getReportActionFromExpensifyCard,
isReopenedAction,
isRetractedAction,
getIntegrationSyncFailedMessage,
getManagerOnVacation,
getVacationer,
Expand Down
8 changes: 5 additions & 3 deletions src/libs/ReportPreviewActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
getReportTransactions,
hasAnyViolations as hasAnyViolationsUtil,
hasMissingSmartscanFields,
hasReportBeenReopened as hasReportBeenReopenedUtils,
hasReportBeenRetracted as hasReportBeenRetractedUtils,
isClosedReport,
isCurrentUserSubmitter,
isExpenseReport,
Expand All @@ -45,7 +47,7 @@ function canSubmit(report: Report, violations: OnyxCollection<TransactionViolati
const isOpen = isOpenReport(report);
const isManager = report.managerID === getCurrentUserAccountID();
const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN;
const hasBeenReopened = report.hasReportBeenReopened ?? false;
const hasBeenRetracted = hasReportBeenReopenedUtils(report) || hasReportBeenRetractedUtils(report);
const isManualSubmitEnabled = getCorrectedAutoReportingFrequency(policy) === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL;

if (!!transactions && transactions?.length > 0 && transactions.every((transaction) => isPending(transaction))) {
Expand All @@ -63,8 +65,8 @@ function canSubmit(report: Report, violations: OnyxCollection<TransactionViolati

const baseCanSubmit = isExpense && (isSubmitter || isManager || isAdmin) && isOpen && !hasAnyViolations && !isAnyReceiptBeingScanned && !!transactions && transactions.length > 0;

// If a report has been reopened, we allow submission regardless of the auto reporting frequency.
if (baseCanSubmit && hasBeenReopened) {
// If a report has been retracted, we allow submission regardless of the auto reporting frequency.
if (baseCanSubmit && hasBeenRetracted) {
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions src/libs/ReportPrimaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
hasExportError as hasExportErrorUtil,
hasOnlyHeldExpenses,
hasReportBeenReopened as hasReportBeenReopenedUtils,
hasReportBeenRetracted as hasReportBeenRetractedUtils,
isArchivedReport,
isClosedReport as isClosedReportUtils,
isCurrentUserSubmitter,
Expand Down Expand Up @@ -87,7 +88,7 @@ function isSubmitAction(report: Report, reportTransactions: Transaction[], polic
}

const isAnyReceiptBeingScanned = reportTransactions?.some((transaction) => isScanning(transaction));
const hasReportBeenReopened = hasReportBeenReopenedUtils(reportActions);
const hasReportBeenRetracted = hasReportBeenReopenedUtils(report, reportActions) || hasReportBeenRetractedUtils(report, reportActions);

if (isAnyReceiptBeingScanned) {
return false;
Expand All @@ -100,7 +101,7 @@ function isSubmitAction(report: Report, reportTransactions: Transaction[], polic
}

const baseIsSubmit = isExpenseReport && isReportSubmitter && isOpenReport && reportTransactions.length !== 0 && transactionAreComplete;
if (hasReportBeenReopened && baseIsSubmit) {
if (hasReportBeenRetracted && baseIsSubmit) {
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions src/libs/ReportSecondaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getTransactionDetails,
hasOnlyHeldExpenses,
hasReportBeenReopened as hasReportBeenReopenedUtils,
hasReportBeenRetracted as hasReportBeenRetractedUtils,
isArchivedReport,
isAwaitingFirstLevelApproval,
isClosedReport as isClosedReportUtils,
Expand Down Expand Up @@ -164,8 +165,8 @@ function isSubmitAction(
return false;
}

const hasReportBeenReopened = hasReportBeenReopenedUtils(reportActions);
if (hasReportBeenReopened && isReportSubmitter) {
const hasReportBeenRetracted = hasReportBeenReopenedUtils(report, reportActions) || hasReportBeenRetractedUtils(report, reportActions);
if (hasReportBeenRetracted && isReportSubmitter) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing the submit button to be missing in 'more' after retracting and holding an expense, we fixed it in #70816

return false;
}

Expand Down
19 changes: 18 additions & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ import {
isReopenedAction,
isReportActionAttachment,
isReportPreviewAction,
isRetractedAction,
isReversedTransaction,
isRoomChangeLogAction,
isSentMoneyReportAction,
Expand Down Expand Up @@ -11263,7 +11264,7 @@ function findReportIDForAction(action?: ReportAction): string | undefined {
?.replace(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`, '');
}

function hasReportBeenReopened(reportActions: OnyxEntry<ReportActions> | ReportAction[], report?: OnyxEntry<Report>): boolean {
function hasReportBeenReopened(report: OnyxEntry<Report>, reportActions?: OnyxEntry<ReportActions> | ReportAction[]): boolean {
// If report object is provided and has the property, use it directly
if (report?.hasReportBeenReopened !== undefined) {
return report.hasReportBeenReopened;
Expand All @@ -11278,6 +11279,21 @@ function hasReportBeenReopened(reportActions: OnyxEntry<ReportActions> | ReportA
return reportActionList.some((action) => isReopenedAction(action));
}

function hasReportBeenRetracted(report: OnyxEntry<Report>, reportActions?: OnyxEntry<ReportActions> | ReportAction[]): boolean {
// If report object is provided and has the property, use it directly
if (report?.hasReportBeenRetracted !== undefined) {
return report.hasReportBeenRetracted;
}

// Fallback to checking actions for backward compatibility
if (!reportActions) {
return false;
}

const reportActionList = Array.isArray(reportActions) ? reportActions : Object.values(reportActions);
return reportActionList.some((action) => isRetractedAction(action));
}

function getMoneyReportPreviewName(action: ReportAction, iouReport: OnyxEntry<Report>, isInvoice?: boolean) {
if (isInvoice && isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW)) {
const originalMessage = getOriginalMessage(action);
Expand Down Expand Up @@ -11704,6 +11720,7 @@ export {
pushTransactionViolationsOnyxData,
navigateOnDeleteExpense,
hasReportBeenReopened,
hasReportBeenRetracted,
getMoneyReportPreviewName,
getNextApproverAccountID,
isWorkspaceTaskReport,
Expand Down
5 changes: 3 additions & 2 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ import {
hasHeldExpenses as hasHeldExpensesReportUtils,
hasNonReimbursableTransactions as hasNonReimbursableTransactionsReportUtils,
hasReportBeenReopened,
hasReportBeenRetracted,
isArchivedReport,
isClosedReport as isClosedReportUtil,
isDraftReport,
Expand Down Expand Up @@ -9481,8 +9482,8 @@ function canSubmitReport(
!isReportArchived &&
transactions.length > 0;
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`] ?? [];
const hasBeenReopened = hasReportBeenReopened(reportActions);
if (baseCanSubmit && hasBeenReopened) {
const hasBeenRetracted = hasReportBeenReopened(report, reportActions) || hasReportBeenRetracted(report, reportActions);
if (baseCanSubmit && hasBeenRetracted) {
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback<
/** Whether the report is cancelled */
isCancelledIOU?: boolean;

/** Whether the report has been retracted */
hasReportBeenRetracted?: boolean;

/** Whether the report has been reopened */
hasReportBeenReopened?: boolean;

Expand Down
1 change: 1 addition & 0 deletions src/types/utils/whitelistedReportKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type WhitelistedReport = OnyxCommon.OnyxValueWithOfflineFeedback<
errors: unknown;
isWaitingOnBankAccount: unknown;
isCancelledIOU: unknown;
hasReportBeenRetracted: unknown;
hasReportBeenReopened: unknown;
isExportedToIntegration: unknown;
hasExportError: unknown;
Expand Down