diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 48cee22a2e53..1a43cdba1d2c 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1677,6 +1677,7 @@ const CONST = { UPDATE_AUTO_HARVESTING: 'POLICYCHANGELOG_UPDATE_AUTOHARVESTING', UPDATE_AUTO_REIMBURSEMENT: 'POLICYCHANGELOG_UPDATE_AUTOREIMBURSEMENT', UPDATE_AUTO_PAY_APPROVED_REPORTS_ENABLED: 'POLICYCHANGELOG_UPDATE_AUTO_PAY_APPROVED_REPORTS_ENABLED', + UPDATE_MCC_GROUP_CATEGORY: 'POLICYCHANGELOG_UPDATE_MCC_GROUP_CATEGORY', UPDATE_AUTO_REPORTING_FREQUENCY: 'POLICYCHANGELOG_UPDATE_AUTOREPORTING_FREQUENCY', UPDATE_BUDGET: 'POLICYCHANGELOG_UPDATE_BUDGET', UPDATE_CATEGORY: 'POLICYCHANGELOG_UPDATE_CATEGORY', diff --git a/src/languages/de.ts b/src/languages/de.ts index c5b42c1bd063..a3206979c26a 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7824,6 +7824,8 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc `Kartenfeed-Tag für das Abrechnungsperiodenende von „${feedName}“ geändert${newValue ? ` in „${newValue}“` : ''}${previousValue ? ` (zuvor „${previousValue}“)` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `${fieldType}-Berichtsfeld „${fieldName}“${defaultValue ? ` mit Standardwert „${defaultValue}“` : ''} hinzugefügt`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `hat die Standardausgabenkategorie für „${mccGroupName}“ in „${newCategory}“ geändert (zuvor „${oldCategory}“)`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? 'aktiviert' : 'deaktiviert'} die Anforderung für Firmenkartenkäufe`, expensifyCardRule: { actionVerb: {block: 'blockiert', allow: 'erlaubt'}, diff --git a/src/languages/en.ts b/src/languages/en.ts index a1652b13cf4c..33e15bdeb134 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7800,6 +7800,8 @@ const translations = { updatedAutoPayApprovedReportsLimit: ({oldLimit, newLimit}: {oldLimit: string; newLimit: string}) => `changed the auto-pay approved reports threshold to "${newLimit}" (previously "${oldLimit}")`, removedAutoPayApprovedReportsLimit: 'removed the auto-pay approved reports threshold', + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `changed the default spend category for "${mccGroupName}" to "${newCategory}" (previously "${oldCategory}")`, changedDefaultApprover: ({newApprover, previousApprover}: {newApprover: string; previousApprover?: string}) => previousApprover ? `changed the default approver to ${newApprover} (previously ${previousApprover})` : `changed the default approver to ${newApprover}`, changedSubmitsToApprover: ({ diff --git a/src/languages/es.ts b/src/languages/es.ts index 2ef683a83d23..17cd153dff70 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -7581,6 +7581,8 @@ ${amount} para ${merchant} - ${date}`, updatedAutoPayApprovedReportsLimit: ({oldLimit, newLimit}: {oldLimit: string; newLimit: string}) => `cambió el umbral de autopago de informes aprobados a "${newLimit}" (previamente "${oldLimit}")`, removedAutoPayApprovedReportsLimit: 'eliminó el umbral de autopago de informes aprobados', + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `cambió la categoría de gasto predeterminada para "${mccGroupName}" a "${newCategory}" (previamente "${oldCategory}")`, changedDefaultApprover: ({newApprover, previousApprover}: {newApprover: string; previousApprover?: string}) => previousApprover ? `cambió el aprobador predeterminado a ${newApprover} (anteriormente ${previousApprover})` : `cambió el aprobador predeterminado a ${newApprover}`, changedSubmitsToApprover: ({ diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 2dc27d7b1f83..561798c1e0c6 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7857,6 +7857,8 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e `a modifié le jour de fin de période de relevé du flux de carte « ${feedName} »${newValue ? ` à « ${newValue} »` : ''}${previousValue ? ` (précédemment « ${previousValue} »)` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `a ajouté le champ de note de frais ${fieldType} « ${fieldName} »${defaultValue ? ` avec la valeur par défaut « ${defaultValue} »` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `a modifié la catégorie de dépense par défaut pour « ${mccGroupName} » en « ${newCategory} » (auparavant « ${oldCategory} »)`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? 'activé' : 'désactivé'} l’exigence d’achats par carte d’entreprise`, expensifyCardRule: { actionVerb: {block: 'bloqué', allow: 'autorisé'}, diff --git a/src/languages/it.ts b/src/languages/it.ts index 7099cd2bf4d1..2aff861ecdd0 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -7812,6 +7812,8 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`, `ha modificato il giorno di fine periodo dell’estratto conto del flusso carta "${feedName}"${newValue ? ` a "${newValue}"` : ''}${previousValue ? ` (in precedenza "${previousValue}")` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `aggiunto campo di report ${fieldType} "${fieldName}"${defaultValue ? ` con valore predefinito "${defaultValue}"` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `ha modificato la categoria di spesa predefinita per "${mccGroupName}" in "${newCategory}" (precedentemente "${oldCategory}")`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? 'abilitato' : 'disabilitato'} il requisito per gli acquisti con carta aziendale`, expensifyCardRule: { actionVerb: {block: 'bloccato', allow: 'consentito'}, diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 11fda2fd0715..ab9e0352d058 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7720,6 +7720,8 @@ ${reportName} `カード明細フィード「${feedName}」の利用明細期間の終了日を変更しました${newValue ? ` を「${newValue}」に` : ''}${previousValue ? ` (以前の値:「${previousValue}」)` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `${fieldType}レポートフィールド「${fieldName}」を追加しました${defaultValue ? ` デフォルト値「${defaultValue}」付き` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `「${mccGroupName}」のデフォルト支出カテゴリーを「${newCategory}」に変更しました(以前は「${oldCategory}」)`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? '有効' : '無効'} の法人カード購入要件`, expensifyCardRule: { actionVerb: {block: 'ブロック済み', allow: '許可済み'}, diff --git a/src/languages/nl.ts b/src/languages/nl.ts index d6c80fc5622f..b40164d6ad6d 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -7782,6 +7782,8 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`, `heeft de einddag van de afrekenperiode van kaartfeed "${feedName}" gewijzigd${newValue ? ` naar "${newValue}"` : ''}${previousValue ? ` (voorheen "${previousValue}")` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `heeft ${fieldType}-rapportveld "${fieldName}" toegevoegd${defaultValue ? ` met standaardwaarde "${defaultValue}"` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `heeft de standaarduitgavencategorie voor ‘${mccGroupName}’ gewijzigd in ‘${newCategory}’ (voorheen ‘${oldCategory}’)`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `vereiste ${enabled ? 'ingeschakeld' : 'uitgeschakeld'} voor bedrijfskaarttransacties`, expensifyCardRule: { actionVerb: {block: 'geblokkeerd', allow: 'toegestaan'}, diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 82e7399524dd..e1dc56e8f011 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7772,6 +7772,8 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`, `zmienił dzień zakończenia okresu rozliczeniowego dla źródła karty „${feedName}”${newValue ? ` na „${newValue}”` : ''}${previousValue ? ` (wcześniej „${previousValue}”)` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `dodano pole raportu typu ${fieldType} „${fieldName}”${defaultValue ? ` z domyślną wartością „${defaultValue}”` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `zmieniono domyślną kategorię wydatków dla „${mccGroupName}” na „${newCategory}” (poprzednio „${oldCategory}”)`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? 'włączone' : 'wyłączone'} wymóg dotyczący zakupów kartą służbową`, expensifyCardRule: { actionVerb: {block: 'zablokowane', allow: 'dozwolone'}, diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 14b51f00ff9f..500f3b56f798 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -7774,6 +7774,8 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`, `changed card feed "${feedName}" statement period end day${newValue ? ` para "${newValue}"` : ''}${previousValue ? `(antes " ${previousValue}")` : ''}`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `adicionou o campo de relatório ${fieldType} "${fieldName}"${defaultValue ? ` com valor padrão "${defaultValue}"` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `alterou a categoria de gasto padrão de "${mccGroupName}" para "${newCategory}" (antes "${oldCategory}")`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? 'ativado' : 'desativado'} o requisito de compras com cartão corporativo`, expensifyCardRule: { actionVerb: {block: 'bloqueado', allow: 'permitido'}, diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 42c93935eb44..cf95cabf5627 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -7573,6 +7573,8 @@ ${reportName} updatedCardFeedLiability: (feedName: string, enabled: boolean) => `允许 ${enabled ? '已启用' : '已禁用'} 持卡人删除卡片交易(卡片流水来源:“${feedName}”)`, updatedCardFeedStatementPeriod: (feedName: string, newValue?: string, previousValue?: string) => `已更改卡片流水“${feedName}”的账单周期截止日${newValue ? ` 为“${newValue}”` : ''}${previousValue ? ` (先前为“${previousValue}”)` : ''}`, + updatedMccGroupCategory: ({mccGroupName, oldCategory, newCategory}: {mccGroupName: string; oldCategory: string; newCategory: string}) => + `已将“${mccGroupName}”的默认支出类别更改为“${newCategory}”(此前为“${oldCategory}”)`, addedReportField: (fieldType: string, fieldName?: string, defaultValue?: string) => `已添加 ${fieldType} 报告字段“${fieldName}”${defaultValue ? ` 默认值为“${defaultValue}”` : ''}`, updatedRequireCompanyCards: ({enabled}: {enabled: boolean}) => `${enabled ? '已启用' : '已禁用'} 公司商务卡消费要求`, expensifyCardRule: { diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index e96137578b7a..381e94ec1403 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -55,6 +55,7 @@ import { getLastVisibleActionIncludingTransactionThread, getLastVisibleMessage, getMarkedReimbursedMessage, + getMccGroupCategoryMessage, getMentionedAccountIDsFromAction, getMessageOfOldDotReportAction, getOneTransactionThreadReportID, @@ -924,6 +925,9 @@ function getLastMessageTextForReport({ if (isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_REIMBURSEMENT)) { lastMessageTextFromReport = getAutoReimbursementMessage(translate, lastReportAction); } + if (isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY)) { + lastMessageTextFromReport = getMccGroupCategoryMessage(translate, lastReportAction); + } if ( isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.ADD_TAX) || isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_TAX) || diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 4c0c4f901228..af6c4cb12b78 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -3456,6 +3456,16 @@ function getAutoReimbursementMessage(translate: LocalizedTranslate, action: Repo return getReportActionText(action); } +function getMccGroupCategoryMessage(translate: LocalizedTranslate, action: ReportAction): string { + const {mccGroupName, oldCategory, newCategory} = getOriginalMessage(action as ReportAction) ?? {}; + + if (!mccGroupName || !oldCategory || !newCategory) { + return getReportActionText(action); + } + + return translate('workspaceActions.updatedMccGroupCategory', {mccGroupName, oldCategory, newCategory}); +} + type DefaultApproverOriginalMessage = { approver: {email: string; name: string; accountID: number}; previousApprover?: {email: string; name: string; accountID: number}; @@ -4732,6 +4742,7 @@ export { getRequireCompanyCardsEnabledMessage, getAutoPayApprovedReportsEnabledMessage, getAutoReimbursementMessage, + getMccGroupCategoryMessage, formatAddressToString, getCompanyAddressUpdateMessage, getDefaultApproverUpdateMessage, diff --git a/src/libs/ReportNameUtils.ts b/src/libs/ReportNameUtils.ts index e533b73e3099..31be98edf940 100644 --- a/src/libs/ReportNameUtils.ts +++ b/src/libs/ReportNameUtils.ts @@ -57,6 +57,7 @@ import { getJoinRequestMessage, getLinkedTransactionID, getMarkedReimbursedMessage, + getMccGroupCategoryMessage, getMessageOfOldDotReportAction, getOriginalMessage, getPlaidBalanceFailureMessage, @@ -582,6 +583,9 @@ function computeReportNameBasedOnReportAction( if (isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_REIMBURSEMENT)) { return getAutoReimbursementMessage(translate, parentReportAction); } + if (isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY)) { + return getMccGroupCategoryMessage(translate, parentReportAction); + } if (isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_DEFAULT_APPROVER)) { return getDefaultApproverUpdateMessage(translate, parentReportAction); } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index b4144fb55b8c..ef79653f646c 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -61,6 +61,7 @@ import { getInvoiceCompanyWebsiteUpdateMessage, getIOUReportIDFromReportActionPreview, getLastVisibleMessage, + getMccGroupCategoryMessage, getMessageOfOldDotReportAction, getOriginalMessage, getPlaidBalanceFailureMessage, @@ -1118,6 +1119,8 @@ function getOptionData({ result.alternateText = getAutoPayApprovedReportsEnabledMessage(translate, lastAction); } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_REIMBURSEMENT) { result.alternateText = getAutoReimbursementMessage(translate, lastAction); + } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY) { + result.alternateText = getMccGroupCategoryMessage(translate, lastAction); } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_DEFAULT_APPROVER) { result.alternateText = getDefaultApproverUpdateMessage(translate, lastAction); } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_SUBMITS_TO) { diff --git a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx index 100aa94f2ede..5caaae4ec16c 100644 --- a/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx @@ -60,6 +60,7 @@ import { getIOUReportIDFromReportActionPreview, getJoinRequestMessage, getMarkedReimbursedMessage, + getMccGroupCategoryMessage, getMemberChangeMessageFragment, getMessageOfOldDotReportAction, getOriginalMessage, @@ -976,6 +977,8 @@ const ContextMenuActions: ContextMenuAction[] = [ Clipboard.setString(getRequireCompanyCardsEnabledMessage(translate, reportAction)); } else if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_REIMBURSEMENT) { Clipboard.setString(getAutoReimbursementMessage(translate, reportAction)); + } else if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY) { + Clipboard.setString(getMccGroupCategoryMessage(translate, reportAction)); } else if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_INVOICE_COMPANY_NAME) { Clipboard.setString(getInvoiceCompanyNameUpdateMessage(translate, reportAction)); } else if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_INVOICE_COMPANY_WEBSITE) { diff --git a/src/pages/inbox/report/actionContents/PolicyChangeLogContent.tsx b/src/pages/inbox/report/actionContents/PolicyChangeLogContent.tsx index ced30612645f..b41ee768ec11 100644 --- a/src/pages/inbox/report/actionContents/PolicyChangeLogContent.tsx +++ b/src/pages/inbox/report/actionContents/PolicyChangeLogContent.tsx @@ -23,6 +23,7 @@ import { getForwardsToUpdateMessage, getInvoiceCompanyNameUpdateMessage, getInvoiceCompanyWebsiteUpdateMessage, + getMccGroupCategoryMessage, getPolicyChangeLogAddEmployeeMessage, getPolicyChangeLogDefaultBillableMessage, getPolicyChangeLogDefaultReimbursableMessage, @@ -144,6 +145,7 @@ const POLICY_CHANGE_LOG_RESOLVERS: Record = { [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_FORWARDS_TO]: (translate, action) => getForwardsToUpdateMessage(translate, action), [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_PAY_APPROVED_REPORTS_ENABLED]: (translate, action) => getAutoPayApprovedReportsEnabledMessage(translate, action), [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_AUTO_REIMBURSEMENT]: (translate, action) => getAutoReimbursementMessage(translate, action), + [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY]: (translate, action) => getMccGroupCategoryMessage(translate, action), [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_INVOICE_COMPANY_NAME]: (translate, action) => getInvoiceCompanyNameUpdateMessage(translate, action), [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_INVOICE_COMPANY_WEBSITE]: (translate, action) => getInvoiceCompanyWebsiteUpdateMessage(translate, action), [CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_REIMBURSER]: (translate, action) => getReimburserUpdateMessage(translate, action), diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 6f137d79f51f..85dafd4894e1 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -524,6 +524,15 @@ type OriginalMessagePolicyChangeLog = { /** New default reimbursable value */ newDefaultReimbursable?: string; + /** MCC group name whose default spend category changed (e.g. "Airlines") */ + mccGroupName?: string; + + /** Previous category name for the MCC group */ + oldCategory?: string; + + /** New category name for the MCC group */ + newCategory?: string; + /** Old default report title formula */ oldDefaultTitle?: string; diff --git a/tests/unit/OptionsListUtilsTest.tsx b/tests/unit/OptionsListUtilsTest.tsx index 17144d330e87..f6d90ad9d891 100644 --- a/tests/unit/OptionsListUtilsTest.tsx +++ b/tests/unit/OptionsListUtilsTest.tsx @@ -5248,6 +5248,35 @@ describe('OptionsListUtils', () => { ); }); }); + describe('UPDATE_MCC_GROUP_CATEGORY action', () => { + it('should surface the friendly MCC group label in the last-message preview', async () => { + const report: Report = createRandomReport(0, undefined); + const changelogAction: ReportAction = { + ...createRandomReportAction(1), + actionName: CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY, + message: [{type: 'COMMENT', text: ''}], + originalMessage: { + mccGroupName: 'Airlines', + oldCategory: 'Insurance', + newCategory: 'Travel', + }, + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, { + [changelogAction.reportActionID]: changelogAction, + }); + + const lastMessage = getLastMessageTextForReport({ + translate: translateLocal, + report, + lastActorDetails: null, + policy: undefined, + isReportArchived: false, + currentUserLogin: CURRENT_USER_EMAIL, + }); + + expect(lastMessage).toBe('changed the default spend category for "Airlines" to "Travel" (previously "Insurance")'); + }); + }); }); describe('getPersonalDetailSearchTerms', () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index ae54db276d3c..bd13321769b2 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -29,6 +29,7 @@ import { getIntegrationSyncFailedMessage, getInvoiceCompanyNameUpdateMessage, getInvoiceCompanyWebsiteUpdateMessage, + getMccGroupCategoryMessage, getModerationFlagState, getOneTransactionThreadReportID, getOriginalMessage, @@ -4502,6 +4503,42 @@ describe('ReportActionsUtils', () => { }); }); + describe('getMccGroupCategoryMessage', () => { + it('should render the friendly MCC group label that the emitter already resolved', () => { + const action = { + actionName: CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY, + reportActionID: '1', + created: '', + originalMessage: { + mccGroupName: 'Airlines', + oldCategory: 'Insurance', + newCategory: 'Travel', + }, + message: [], + } as ReportAction; + + const result = getMccGroupCategoryMessage(translateLocal, action); + expect(result).toBe('changed the default spend category for "Airlines" to "Travel" (previously "Insurance")'); + }); + + it('should pass through a fallback raw groupID when the emitter could not resolve it', () => { + const action = { + actionName: CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY, + reportActionID: '1', + created: '', + originalMessage: { + mccGroupName: 'spaceflight', + oldCategory: 'Travel', + newCategory: 'Equipment', + }, + message: [], + } as ReportAction; + + const result = getMccGroupCategoryMessage(translateLocal, action); + expect(result).toBe('changed the default spend category for "spaceflight" to "Equipment" (previously "Travel")'); + }); + }); + describe('isNewerReportAction', () => { const makeAction = (overrides: Partial): ReportAction => ({ diff --git a/tests/unit/ReportNameUtilsTest.ts b/tests/unit/ReportNameUtilsTest.ts index 9c18e5886707..b250bdd26010 100644 --- a/tests/unit/ReportNameUtilsTest.ts +++ b/tests/unit/ReportNameUtilsTest.ts @@ -859,6 +859,44 @@ describe('ReportNameUtils', () => { ); expect(name).toBe('changed card feed "Visa Commercial" statement period end day to "15" (previously "20")'); }); + + test('UPDATE_MCC_GROUP_CATEGORY parent action renders the friendly MCC group label', () => { + const thread: Report = createWorkspaceThread(75); + const parentAction: ReportAction = { + actionName: CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY, + reportActionID: String(thread.parentReportActionID), + message: [], + created: '', + lastModified: '', + actorAccountID: 1, + person: [], + originalMessage: { + mccGroupName: 'Airlines', + oldCategory: 'Insurance', + newCategory: 'Travel', + }, + } as unknown as ReportAction; + + const parentId = String(thread.parentReportID); + const actionId = String(thread.parentReportActionID); + const reportActionsCollection: Record = { + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentId}`]: { + [actionId]: parentAction, + }, + }; + + const name = computeReportName( + thread, + emptyCollections.reports, + emptyCollections.policies, + undefined, + undefined, + participantsPersonalDetails, + reportActionsCollection, + currentUserAccountID, + ); + expect(name).toBe('changed the default spend category for "Airlines" to "Travel" (previously "Insurance")'); + }); }); describe('getReportName (derived value vs fallback)', () => { diff --git a/tests/unit/SidebarUtilsTest.ts b/tests/unit/SidebarUtilsTest.ts index 058c41917496..13e734cf3286 100644 --- a/tests/unit/SidebarUtilsTest.ts +++ b/tests/unit/SidebarUtilsTest.ts @@ -3438,6 +3438,53 @@ describe('SidebarUtils', () => { expect(result?.isConciergeChat).toBe(false); }); }); + + it('renders the UPDATE_MCC_GROUP_CATEGORY changelog with the friendly MCC group label as alternate text', async () => { + const report: Report = { + ...createRandomReport(4, 'policyAdmins'), + lastVisibleActionCreated: '2026-04-22 12:30:03.784', + }; + const lastAction: ReportAction = { + ...createRandomReportAction(2), + message: [{type: 'COMMENT', html: '', text: '', isDeletedParentAction: false, deleted: ''}], + actionName: CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_MCC_GROUP_CATEGORY, + actorAccountID: 18921695, + person: [{type: 'TEXT', style: 'strong', text: 'Admin'}], + originalMessage: { + mccGroupName: 'Airlines', + oldCategory: 'Insurance', + newCategory: 'Travel', + }, + }; + const reportActions: ReportActions = {[lastAction.reportActionID]: lastAction}; + await act(async () => { + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, reportActions); + }); + + const result = SidebarUtils.getOptionData({ + report, + reportAttributes: undefined, + reportNameValuePairs: {}, + personalDetails: {}, + policy: undefined, + invoiceReceiverPolicy: undefined, + parentReportAction: undefined, + conciergeReportID: '', + oneTransactionThreadReport: undefined, + card: undefined, + translate: translateLocal, + localeCompare, + lastAction, + lastActionReport: undefined, + isReportArchived: undefined, + currentUserAccountID: 0, + currentUserLogin: CURRENT_USER_LOGIN, + reportAttributesDerived: undefined, + }); + + expect(result?.alternateText).toBe('changed the default spend category for "Airlines" to "Travel" (previously "Insurance")'); + }); }); describe('sortReportsToDisplayInLHN', () => {