diff --git a/src/CONST.ts b/src/CONST.ts index ac4b9562672d..eb5d91432f7f 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1058,6 +1058,7 @@ const CONST = { CREATED: 'CREATED', DELEGATE_SUBMIT: 'DELEGATESUBMIT', // OldDot Action DELETED_ACCOUNT: 'DELETEDACCOUNT', // Deprecated OldDot Action + DELETED_TRANSACTION: 'DELETEDTRANSACTION', DISMISSED_VIOLATION: 'DISMISSEDVIOLATION', DONATION: 'DONATION', // Deprecated OldDot Action EXPORTED_TO_CSV: 'EXPORTCSV', // OldDot Action diff --git a/src/languages/en.ts b/src/languages/en.ts index 7c3bd33c8b2a..b750cb6cd63d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -59,6 +59,7 @@ import type { DelegatorParams, DeleteActionParams, DeleteConfirmationParams, + DeleteTransactionParams, DidSplitAmountMessageParams, EarlyDiscountSubtitleParams, EarlyDiscountTitleParams, @@ -881,6 +882,7 @@ const translations = { canceled: 'Canceled', posted: 'Posted', deleteReceipt: 'Delete receipt', + deletedTransaction: ({amount, merchant}: DeleteTransactionParams) => `deleted an expense on this report, ${merchant} - ${amount}`, pendingMatchWithCreditCard: 'Receipt pending match with card transaction', pendingMatchWithCreditCardDescription: 'Receipt pending match with card transaction. Mark as cash to cancel.', markAsCash: 'Mark as cash', diff --git a/src/languages/es.ts b/src/languages/es.ts index 140891c7a4fa..231ed888e8d2 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -58,6 +58,7 @@ import type { DelegatorParams, DeleteActionParams, DeleteConfirmationParams, + DeleteTransactionParams, DidSplitAmountMessageParams, EarlyDiscountSubtitleParams, EarlyDiscountTitleParams, @@ -880,6 +881,7 @@ const translations = { pendingMatchWithCreditCardDescription: 'Recibo pendiente de adjuntar con la transacción de la tarjeta. Márcalo como efectivo para cancelar.', markAsCash: 'Marcar como efectivo', routePending: 'Ruta pendiente...', + deletedTransaction: ({amount, merchant}: DeleteTransactionParams) => `eliminó un gasto de este informe, ${merchant} - ${amount}`, receiptIssuesFound: () => ({ one: 'Problema encontrado', other: 'Problemas encontrados', diff --git a/src/languages/params.ts b/src/languages/params.ts index 9d28f198b704..59e4acf74f6a 100644 --- a/src/languages/params.ts +++ b/src/languages/params.ts @@ -115,6 +115,11 @@ type RequestCountParams = { pendingReceipts: number; }; +type DeleteTransactionParams = { + amount: string; + merchant: string; +}; + type SettleExpensifyCardParams = { formattedAmount: string; }; @@ -725,6 +730,7 @@ export type { ReportArchiveReasonsRemovedFromPolicyParams, RequestAmountParams, RequestCountParams, + DeleteTransactionParams, RequestedAmountMessageParams, ResolutionConstraintsParams, RoomNameReservedErrorParams, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index dbe768199dde..2ca221805459 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -64,7 +64,7 @@ import {autoSwitchToFocusMode} from './actions/PriorityMode'; import {hasCreditBankAccount} from './actions/ReimbursementAccount/store'; import {handleReportChanged} from './actions/Report'; import {isAnonymousUser as isAnonymousUserSession} from './actions/Session'; -import {convertToDisplayString} from './CurrencyUtils'; +import {convertToDisplayString, getCurrencySymbol} from './CurrencyUtils'; import DateUtils from './DateUtils'; import {hasValidDraftComment} from './DraftCommentUtils'; import {getMicroSecondOnyxErrorWithTranslationKey} from './ErrorUtils'; @@ -5137,6 +5137,17 @@ function getWorkspaceNameUpdatedMessage(action: ReportAction) { return Str.htmlEncode(message); } +function getDeletedTransactionMessage(action: ReportAction) { + const deletedTransactionOriginalMessage = getOriginalMessage(action as ReportAction) ?? {}; + const amount = Math.abs(deletedTransactionOriginalMessage.amount ?? 0) / 100; + const currency = getCurrencySymbol(deletedTransactionOriginalMessage.currency ?? ''); + const message = translateLocal('iou.deletedTransaction', { + amount: `${currency}${amount}`, + merchant: deletedTransactionOriginalMessage.merchant ?? '', + }); + return message; +} + /** * @param iouReportID - the report ID of the IOU report the action belongs to * @param type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay, split) @@ -8969,6 +8980,7 @@ export { getIOUForwardedMessage, getRejectedReportMessage, getWorkspaceNameUpdatedMessage, + getDeletedTransactionMessage, getUpgradeWorkspaceMessage, getDowngradeWorkspaceMessage, getReportAutomaticallySubmittedMessage, diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 91481cd30754..bafef0d7f6a4 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -64,6 +64,7 @@ import { canHoldUnholdReportAction, changeMoneyRequestHoldStatus, getChildReportNotificationPreference as getChildReportNotificationPreferenceReportUtils, + getDeletedTransactionMessage, getDowngradeWorkspaceMessage, getIOUApprovedMessage, getIOUForwardedMessage, @@ -545,6 +546,8 @@ const ContextMenuActions: ContextMenuAction[] = [ setClipboardMessage(getPolicyChangeLogChangeRoleMessage(reportAction)); } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_EMPLOYEE) { setClipboardMessage(getPolicyChangeLogDeleteMemberMessage(reportAction)); + } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.DELETED_TRANSACTION) { + setClipboardMessage(getDeletedTransactionMessage(reportAction)); } else if (isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.INTEGRATION_SYNC_FAILED)) { const {label, errorMessage} = getOriginalMessage(reportAction) ?? {label: '', errorMessage: ''}; setClipboardMessage(translateLocal('report.actions.type.integrationSyncFailed', {label, errorMessage})); diff --git a/src/pages/home/report/PureReportActionItem.tsx b/src/pages/home/report/PureReportActionItem.tsx index ee09576d1a4d..ed82c13e4985 100644 --- a/src/pages/home/report/PureReportActionItem.tsx +++ b/src/pages/home/report/PureReportActionItem.tsx @@ -11,7 +11,7 @@ import DisplayNames from '@components/DisplayNames'; import Hoverable from '@components/Hoverable'; import MentionReportContext from '@components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/MentionReportContext'; import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; +import {Eye} from '@components/Icon/Expensicons'; import InlineSystemMessage from '@components/InlineSystemMessage'; import KYCWall from '@components/KYCWall'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -89,6 +89,7 @@ import { import { canWriteInReport, chatIncludesConcierge, + getDeletedTransactionMessage, getDisplayNamesWithTooltips, getIconsForParticipants, getIOUApprovedMessage, @@ -862,6 +863,8 @@ function PureReportActionItem({ children = ; } else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.UNHOLD) { children = ; + } else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.DELETED_TRANSACTION) { + children = ; } else if (action.actionName === CONST.REPORT.ACTIONS.TYPE.MERGED_WITH_CASH_TRANSACTION) { children = ; } else if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.DISMISSED_VIOLATION)) { @@ -1173,7 +1176,7 @@ function PureReportActionItem({ diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 1bae98f96d50..dd619c01e797 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -370,6 +370,18 @@ type OriginalMessageModifiedExpense = { attendees?: string; }; +/** Model of the `deleted transaction` report action */ +type OriginalMessageDeletedTransaction = { + /** The merchant of the transaction */ + merchant?: string; + + /** The amount of the transaction */ + amount?: number; + + /** The currency of the transaction */ + currency?: string; +}; + /** Model of `reimbursement queued` report action */ type OriginalMessageReimbursementQueued = { /** How is the payment getting reimbursed */ @@ -637,6 +649,7 @@ type OriginalMessageMap = { [CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL]: OriginalMessageCard; [CONST.REPORT.ACTIONS.TYPE.CARD_ASSIGNED]: OriginalMessageCard; [CONST.REPORT.ACTIONS.TYPE.INTEGRATION_SYNC_FAILED]: OriginalMessageIntegrationSyncFailed; + [CONST.REPORT.ACTIONS.TYPE.DELETED_TRANSACTION]: OriginalMessageDeletedTransaction; } & OldDotOriginalMessageMap & { [T in ValueOf]: OriginalMessageChangeLog; } & {