diff --git a/src/languages/en.ts b/src/languages/en.ts
index 478abaefe5c8..c44ac6f2cedf 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -915,7 +915,11 @@ const translations = {
managerApprovedAmount: ({manager, amount}: ManagerApprovedAmountParams) => `${manager} approved ${amount}`,
payerSettled: ({amount}: PayerSettledParams) => `paid ${amount}`,
payerSettledWithMissingBankAccount: ({amount}: PayerSettledParams) => `paid ${amount}. Add a bank account to receive your payment.`,
+ automaticallyApprovedAmount: ({amount}: ApprovedAmountParams) =>
+ `automatically approved ${amount} via workspace rules`,
approvedAmount: ({amount}: ApprovedAmountParams) => `approved ${amount}`,
+ automaticallyForwardedAmount: ({amount}: ForwardedAmountParams) =>
+ `automatically approved ${amount} via workspace rules`,
forwardedAmount: ({amount}: ForwardedAmountParams) => `approved ${amount}`,
rejectedThisReport: 'rejected this report',
waitingOnBankAccount: ({submitterDisplayName}: WaitingOnBankAccountParams) => `started settling up. Payment is on hold until ${submitterDisplayName} adds a bank account.`,
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 771285c97c2e..76cb22772f88 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -909,7 +909,11 @@ const translations = {
managerApprovedAmount: ({manager, amount}: ManagerApprovedAmountParams) => `${manager} aprobó ${amount}`,
payerSettled: ({amount}: PayerSettledParams) => `pagó ${amount}`,
payerSettledWithMissingBankAccount: ({amount}: PayerSettledParams) => `pagó ${amount}. Agrega una cuenta bancaria para recibir tu pago.`,
+ automaticallyApprovedAmount: ({amount}: ApprovedAmountParams) =>
+ `aprobado automáticamente ${amount} según las reglas del espacio de trabajo`,
approvedAmount: ({amount}: ApprovedAmountParams) => `aprobó ${amount}`,
+ automaticallyForwardedAmount: ({amount}: ForwardedAmountParams) =>
+ `aprobado automáticamente ${amount} según las reglas del espacio de trabajo`,
forwardedAmount: ({amount}: ForwardedAmountParams) => `aprobó ${amount}`,
rejectedThisReport: 'rechazó este informe',
waitingOnBankAccount: ({submitterDisplayName}: WaitingOnBankAccountParams) => `inició el pago, pero no se procesará hasta que ${submitterDisplayName} añada una cuenta bancaria`,
diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts
index 11d8385d538b..a004974b88e4 100644
--- a/src/libs/OptionsListUtils.ts
+++ b/src/libs/OptionsListUtils.ts
@@ -717,10 +717,20 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails
} else {
lastMessageTextFromReport = ReportUtils.getIOUSubmittedMessage(lastReportAction);
}
- } else if (lastReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.APPROVED) {
- lastMessageTextFromReport = ReportUtils.getIOUApprovedMessage(lastReportAction);
- } else if (lastReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.FORWARDED) {
- lastMessageTextFromReport = ReportUtils.getIOUForwardedMessage(lastReportAction, report);
+ } else if (ReportActionUtils.isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.APPROVED)) {
+ const {automaticAction} = ReportActionUtils.getOriginalMessage(lastReportAction) ?? {};
+ if (automaticAction) {
+ lastMessageTextFromReport = ReportUtils.getReportAutomaticallyApprovedMessage(lastReportAction);
+ } else {
+ lastMessageTextFromReport = ReportUtils.getIOUApprovedMessage(lastReportAction);
+ }
+ } else if (ReportActionUtils.isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.FORWARDED)) {
+ const {automaticAction} = ReportActionUtils.getOriginalMessage(lastReportAction) ?? {};
+ if (automaticAction) {
+ lastMessageTextFromReport = ReportUtils.getReportAutomaticallyForwardedMessage(lastReportAction, reportID);
+ } else {
+ lastMessageTextFromReport = ReportUtils.getIOUForwardedMessage(lastReportAction, report);
+ }
} else if (lastReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REJECTED) {
lastMessageTextFromReport = ReportUtils.getRejectedReportMessage();
} else if (ReportActionUtils.isActionableAddPaymentCard(lastReportAction)) {
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 4485c597b0a4..09b05090de8b 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3819,15 +3819,27 @@ function getReportName(
ReportActionsUtils.isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED) ||
ReportActionsUtils.isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED_AND_CLOSED)
) {
+ const {harvesting} = ReportActionsUtils.getOriginalMessage(parentReportAction) ?? {};
+ if (harvesting) {
+ return Parser.htmlToText(getReportAutomaticallySubmittedMessage(parentReportAction));
+ }
return getIOUSubmittedMessage(parentReportAction);
}
- if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.FORWARDED) {
+ if (ReportActionsUtils.isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.FORWARDED)) {
+ const {automaticAction} = ReportActionsUtils.getOriginalMessage(parentReportAction) ?? {};
+ if (automaticAction) {
+ return Parser.htmlToText(getReportAutomaticallyForwardedMessage(parentReportAction, reportID));
+ }
return getIOUForwardedMessage(parentReportAction, report);
}
if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REJECTED) {
return getRejectedReportMessage();
}
- if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.APPROVED) {
+ if (ReportActionsUtils.isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.APPROVED)) {
+ const {automaticAction} = ReportActionsUtils.getOriginalMessage(parentReportAction) ?? {};
+ if (automaticAction) {
+ return Parser.htmlToText(getReportAutomaticallyApprovedMessage(parentReportAction));
+ }
return getIOUApprovedMessage(parentReportAction);
}
@@ -4573,7 +4585,11 @@ function getIOUSubmittedMessage(reportAction: ReportAction) {
+ return Localize.translateLocal('iou.automaticallyApprovedAmount', {amount: getFormattedAmount(reportAction)});
+}
+
+function getIOUApprovedMessage(reportAction: ReportAction) {
return Localize.translateLocal('iou.approvedAmount', {amount: getFormattedAmount(reportAction)});
}
@@ -4581,7 +4597,26 @@ function getIOUApprovedMessage(reportAction: ReportAction) {
* We pass the reportID as older FORWARDED actions do not have the amount & currency stored in the message
* so we retrieve the amount from the report instead
*/
-function getIOUForwardedMessage(reportAction: ReportAction, reportOrID: OnyxInputOrEntry | string) {
+function getReportAutomaticallyForwardedMessage(reportAction: ReportAction, reportOrID: OnyxInputOrEntry | string) {
+ const expenseReport = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID;
+ const originalMessage = ReportActionsUtils.getOriginalMessage(reportAction) as OriginalMessageIOU;
+ let formattedAmount;
+
+ // Older FORWARDED action might not have the amount stored in the original message, we'll fallback to getting the amount from the report instead.
+ if (originalMessage?.amount) {
+ formattedAmount = getFormattedAmount(reportAction);
+ } else {
+ formattedAmount = CurrencyUtils.convertToDisplayString(getMoneyRequestSpendBreakdown(expenseReport).totalDisplaySpend, expenseReport?.currency);
+ }
+
+ return Localize.translateLocal('iou.automaticallyForwardedAmount', {amount: formattedAmount});
+}
+
+/**
+ * We pass the reportID as older FORWARDED actions do not have the amount & currency stored in the message
+ * so we retrieve the amount from the report instead
+ */
+function getIOUForwardedMessage(reportAction: ReportAction, reportOrID: OnyxInputOrEntry | string) {
const expenseReport = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID;
const originalMessage = ReportActionsUtils.getOriginalMessage(reportAction) as OriginalMessageIOU;
let formattedAmount;
@@ -7232,7 +7267,7 @@ function getIOUReportActionDisplayMessage(reportAction: OnyxEntry,
const amount = TransactionUtils.getAmount(transaction, !isEmptyObject(iouReport) && isExpenseReport(iouReport)) ?? 0;
const formattedAmount = CurrencyUtils.convertToDisplayString(amount, TransactionUtils.getCurrency(transaction)) ?? '';
- const isRequestSettled = isSettled(originalMessage?.IOUReportID);
+ const isRequestSettled = isSettled(IOUReportID);
const isApproved = isReportApproved(iouReport);
if (isRequestSettled) {
return Localize.translateLocal('iou.payerSettled', {
@@ -8172,7 +8207,9 @@ export {
getGroupChatName,
getIOUReportActionDisplayMessage,
getIOUReportActionMessage,
+ getReportAutomaticallyApprovedMessage,
getIOUApprovedMessage,
+ getReportAutomaticallyForwardedMessage,
getIOUForwardedMessage,
getRejectedReportMessage,
getWorkspaceNameUpdatedMessage,
diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
index 7e420f548106..80f0b1de8a46 100644
--- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
+++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
@@ -443,13 +443,31 @@ const ContextMenuActions: ContextMenuAction[] = [
ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED) ||
ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED_AND_CLOSED)
) {
- const displayMessage = ReportUtils.getIOUSubmittedMessage(reportAction);
+ const {harvesting} = ReportActionsUtils.getOriginalMessage(reportAction) ?? {};
+ let displayMessage = '';
+ if (harvesting) {
+ displayMessage = ReportUtils.getReportAutomaticallySubmittedMessage(reportAction);
+ } else {
+ displayMessage = ReportUtils.getIOUSubmittedMessage(reportAction);
+ }
Clipboard.setString(displayMessage);
- } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.APPROVED) {
- const displayMessage = ReportUtils.getIOUApprovedMessage(reportAction);
+ } else if (ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.APPROVED)) {
+ const {automaticAction} = ReportActionsUtils.getOriginalMessage(reportAction) ?? {};
+ let displayMessage = '';
+ if (automaticAction) {
+ displayMessage = ReportUtils.getReportAutomaticallyApprovedMessage(reportAction);
+ } else {
+ displayMessage = ReportUtils.getIOUApprovedMessage(reportAction);
+ }
Clipboard.setString(displayMessage);
- } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.FORWARDED) {
- const displayMessage = ReportUtils.getIOUForwardedMessage(reportAction, reportID);
+ } else if (ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.FORWARDED)) {
+ const {automaticAction} = ReportActionsUtils.getOriginalMessage(reportAction) ?? {};
+ let displayMessage = '';
+ if (automaticAction) {
+ displayMessage = ReportUtils.getReportAutomaticallyForwardedMessage(reportAction, reportID);
+ } else {
+ displayMessage = ReportUtils.getIOUForwardedMessage(reportAction, reportID);
+ }
Clipboard.setString(displayMessage);
} else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REJECTED) {
const displayMessage = ReportUtils.getRejectedReportMessage();
diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx
index 0d2efbfded2c..5d63b7a03952 100644
--- a/src/pages/home/report/ReportActionItem.tsx
+++ b/src/pages/home/report/ReportActionItem.tsx
@@ -646,10 +646,28 @@ function ReportActionItem({
} else {
children = ;
}
- } else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.APPROVED) {
- children = ;
- } else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.FORWARDED) {
- children = ;
+ } else if (ReportActionsUtils.isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.APPROVED)) {
+ const wasAutoApproved = ReportActionsUtils.getOriginalMessage(action)?.automaticAction ?? false;
+ if (wasAutoApproved) {
+ children = (
+
+ ${ReportUtils.getReportAutomaticallyApprovedMessage(action)}`} />
+
+ );
+ } else {
+ children = ;
+ }
+ } else if (ReportActionsUtils.isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.FORWARDED)) {
+ const wasAutoForwarded = ReportActionsUtils.getOriginalMessage(action)?.automaticAction ?? false;
+ if (wasAutoForwarded) {
+ children = (
+
+ ${ReportUtils.getReportAutomaticallyForwardedMessage(action, reportID)}`} />
+
+ );
+ } else {
+ children = ;
+ }
} else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.REJECTED) {
children = ;
} else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.HOLD) {
diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts
index 73377e81c4ef..eb5db8a0dbbf 100644
--- a/src/types/onyx/OriginalMessage.ts
+++ b/src/types/onyx/OriginalMessage.ts
@@ -438,6 +438,9 @@ type OriginalMessageApproved = {
/** Approved expense amount */
amount: number;
+ /** Was the action created automatically, not by a human */
+ automaticAction?: boolean;
+
/** Currency of the approved expense amount */
currency: string;
@@ -450,6 +453,9 @@ type OriginalMessageForwarded = {
/** Forwarded expense amount */
amount: number;
+ /** Was the action created automatically, not by a human */
+ automaticAction?: boolean;
+
/** Currency of the forwarded expense amount */
currency: string;
diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts
index 091a8cafa37e..e4eee7241d80 100644
--- a/tests/unit/ReportUtilsTest.ts
+++ b/tests/unit/ReportUtilsTest.ts
@@ -270,6 +270,28 @@ describe('ReportUtils', () => {
});
});
});
+
+ describe('ParentReportAction is', () => {
+ test('Manually Submitted Report Action', () => {
+ const threadOfSubmittedReportAction = {
+ ...LHNTestUtils.getFakeReport(),
+ type: CONST.REPORT.TYPE.EXPENSE,
+ stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
+ statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
+ parentReportID: '101',
+ policyID: policy.id,
+ };
+ const submittedParentReportAction = {
+ actionName: CONST.REPORT.ACTIONS.TYPE.SUBMITTED,
+ originalMessage: {
+ amount: 169,
+ currency: 'USD',
+ },
+ } as ReportAction;
+
+ expect(ReportUtils.getReportName(threadOfSubmittedReportAction, policy, submittedParentReportAction)).toBe('submitted $1.69');
+ });
+ });
});
describe('requiresAttentionFromCurrentUser', () => {