diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index 378262c6ef89..576ca6c81206 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -8,6 +8,7 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ReceiptAudit, {ReceiptAuditMessages} from '@components/ReceiptAudit'; import ReceiptEmptyState from '@components/ReceiptEmptyState'; import useActiveRoute from '@hooks/useActiveRoute'; +import useEnvironment from '@hooks/useEnvironment'; import useGetIOUReportFromReportAction from '@hooks/useGetIOUReportFromReportAction'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -97,6 +98,7 @@ function MoneyRequestReceiptView({ }: MoneyRequestReceiptViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const {environmentURL} = useEnvironment(); const {shouldUseNarrowLayout, isInNarrowPaneModal} = useResponsiveLayout(); const {getReportRHPActiveRoute} = useActiveRoute(); const parentReportID = report?.parentReportID; @@ -136,6 +138,7 @@ function MoneyRequestReceiptView({ const isReportArchived = useReportIsArchived(report?.reportID); const isEditable = !!canUserPerformWriteActionReportUtils(report, isReportArchived) && !readonly; const canEdit = isMoneyRequestAction(parentReportAction) && canEditMoneyRequest(parentReportAction, isChatReportArchived, moneyRequestReport, policy, transaction) && isEditable; + const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(report?.policyID)}`; const canEditReceipt = isEditable && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT, undefined, isChatReportArchived); @@ -170,7 +173,7 @@ function MoneyRequestReceiptView({ const isReceiptFieldViolation = receiptFieldViolationNames.has(violation.name); const isReceiptImageViolation = receiptImageViolationNames.has(violation.name); if (isReceiptFieldViolation || isReceiptImageViolation) { - const violationMessage = ViolationsUtils.getViolationTranslation(violation, translate, canEdit); + const violationMessage = ViolationsUtils.getViolationTranslation(violation, translate, canEdit, undefined, companyCardPageURL); allViolations.push(violationMessage); if (isReceiptImageViolation) { imageViolations.push(violationMessage); @@ -178,7 +181,7 @@ function MoneyRequestReceiptView({ } } return [imageViolations, allViolations]; - }, [transactionViolations, translate, canEdit]); + }, [transactionViolations, translate, canEdit, companyCardPageURL]); const receiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED); const customRulesViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.CUSTOM_RULES); diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 9943c60aab24..f7c51c627df1 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -14,6 +14,7 @@ import Text from '@components/Text'; import ViolationMessages from '@components/ViolationMessages'; import {WideRHPContext} from '@components/WideRHPContextProvider'; import useActiveRoute from '@hooks/useActiveRoute'; +import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -129,6 +130,7 @@ function MoneyRequestView({ const theme = useTheme(); const StyleUtils = useStyleUtils(); const {isOffline} = useNetwork(); + const {environmentURL} = useEnvironment(); const {translate, toLocaleDigit} = useLocalize(); const {getReportRHPActiveRoute} = useActiveRoute(); const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH, {canBeMissing: true}); @@ -246,6 +248,7 @@ function MoneyRequestView({ const isReportArchived = useReportIsArchived(report?.reportID); const isEditable = !!canUserPerformWriteActionReportUtils(report, isReportArchived) && !readonly; const canEdit = isMoneyRequestAction(parentReportAction) && canEditMoneyRequest(parentReportAction, isChatReportArchived, moneyRequestReport, policy, transaction) && isEditable; + const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(report?.policyID)}`; const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(transaction); const isSplitAvailable = moneyRequestReport && transaction && isSplitAction(moneyRequestReport, [transaction], policy); @@ -415,7 +418,7 @@ function MoneyRequestView({ // Return violations if there are any if (field !== 'merchant' && hasViolations(field, data, policyHasDependentTags, tagValue)) { const violations = getViolationsForField(field, data, policyHasDependentTags, tagValue); - return `${violations.map((violation) => ViolationsUtils.getViolationTranslation(violation, translate, canEdit)).join('. ')}.`; + return `${violations.map((violation) => ViolationsUtils.getViolationTranslation(violation, translate, canEdit, undefined, companyCardPageURL)).join('. ')}.`; } return ''; @@ -437,6 +440,7 @@ function MoneyRequestView({ canEditMerchant, canEdit, isCustomUnitOutOfPolicy, + companyCardPageURL, ], ); @@ -898,6 +902,7 @@ function MoneyRequestView({ textStyle={[styles.ph0]} isLast canEdit={canEdit} + companyCardPageURL={companyCardPageURL} /> )} diff --git a/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx b/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx index 203e75adc811..96faf82f92d1 100644 --- a/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx +++ b/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx @@ -10,6 +10,7 @@ import ReportActionItemImages from '@components/ReportActionItem/ReportActionIte import UserInfoCellsWithArrow from '@components/SelectionListWithSections/Search/UserInfoCellsWithArrow'; import Text from '@components/Text'; import TransactionPreviewSkeletonView from '@components/TransactionPreviewSkeletonView'; +import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReportIsArchived from '@hooks/useReportIsArchived'; @@ -33,6 +34,7 @@ import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type {TransactionPreviewContentProps} from './types'; function TransactionPreviewContent({ @@ -61,6 +63,7 @@ function TransactionPreviewContent({ const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); + const {environmentURL} = useEnvironment(); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: true}); const isParentPolicyExpenseChat = isPolicyExpenseChat(chatReport); @@ -103,7 +106,8 @@ function TransactionPreviewContent({ const firstViolation = violations.at(0); const isIOUActionType = isMoneyRequestAction(action); const canEdit = isIOUActionType && canEditMoneyRequest(action, isChatReportArchived, report, policy, transaction); - const violationMessage = firstViolation ? ViolationsUtils.getViolationTranslation(firstViolation, translate, canEdit) : undefined; + const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(report?.policyID)}`; + const violationMessage = firstViolation ? ViolationsUtils.getViolationTranslation(firstViolation, translate, canEdit, undefined, companyCardPageURL) : undefined; const previewText = useMemo( () => diff --git a/src/components/TransactionItemRow/TransactionItemRowRBR.tsx b/src/components/TransactionItemRow/TransactionItemRowRBR.tsx index ae0fc95984ed..0e8b99d29636 100644 --- a/src/components/TransactionItemRow/TransactionItemRowRBR.tsx +++ b/src/components/TransactionItemRow/TransactionItemRowRBR.tsx @@ -4,6 +4,7 @@ import {View} from 'react-native'; import Icon from '@components/Icon'; import {DotIndicator} from '@components/Icon/Expensicons'; import RenderHTML from '@components/RenderHTML'; +import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useTheme from '@hooks/useTheme'; @@ -13,6 +14,7 @@ import {isSettled} from '@libs/ReportUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type {Report, TransactionViolation} from '@src/types/onyx'; import type Transaction from '@src/types/onyx/Transaction'; @@ -37,9 +39,11 @@ function TransactionItemRowRBR({transaction, violations, report, containerStyles const styles = useThemeStyles(); const {translate} = useLocalize(); const theme = useTheme(); + const {environmentURL} = useEnvironment(); const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transaction.reportID}`, { canBeMissing: true, }); + const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(report?.policyID)}`; const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${report?.policyID}`, {canBeMissing: true}); const transactionThreadId = reportActions ? getIOUActionForTransactionID(Object.values(reportActions ?? {}), transaction.transactionID)?.childReportID : undefined; const [transactionThreadActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadId}`, { @@ -53,6 +57,7 @@ function TransactionItemRowRBR({transaction, violations, report, containerStyles missingFieldError, Object.values(transactionThreadActions ?? {}), policyTags, + companyCardPageURL, ); return ( diff --git a/src/components/ViolationMessages.tsx b/src/components/ViolationMessages.tsx index ab0543f58011..77b17dd44fad 100644 --- a/src/components/ViolationMessages.tsx +++ b/src/components/ViolationMessages.tsx @@ -7,14 +7,21 @@ import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import type {TransactionViolation} from '@src/types/onyx'; import Text from './Text'; -type ViolationMessagesProps = {violations: TransactionViolation[]; isLast?: boolean; containerStyle?: StyleProp; textStyle?: StyleProp; canEdit: boolean}; +type ViolationMessagesProps = { + violations: TransactionViolation[]; + isLast?: boolean; + containerStyle?: StyleProp; + textStyle?: StyleProp; + canEdit: boolean; + companyCardPageURL?: string; +}; -export default function ViolationMessages({violations, isLast, containerStyle, textStyle, canEdit}: ViolationMessagesProps) { +export default function ViolationMessages({violations, isLast, containerStyle, textStyle, canEdit, companyCardPageURL}: ViolationMessagesProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const violationMessages = useMemo( - () => violations.map((violation) => [violation.name, ViolationsUtils.getViolationTranslation(violation, translate, canEdit)]), - [canEdit, translate, violations], + () => violations.map((violation) => [violation.name, ViolationsUtils.getViolationTranslation(violation, translate, canEdit, undefined, companyCardPageURL)]), + [canEdit, translate, violations, companyCardPageURL], ); return ( diff --git a/src/languages/de.ts b/src/languages/de.ts index 7404a5192a6c..98b592139e0e 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -6829,14 +6829,14 @@ ${amount} für ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Überprüfung erforderlich', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'Kassenbon kann aufgrund einer unterbrochenen Bankverbindung nicht automatisch zugeordnet werden.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Kassenbon kann aufgrund einer unterbrochenen Bankverbindung, die ${email} beheben muss, nicht automatisch zugeordnet werden.` - : 'Kassenbon kann aufgrund einer unterbrochenen Bankverbindung nicht automatisch zugeordnet werden.'; + ? `Bankverbindung unterbrochen. Jetzt wieder verbinden, um den Beleg zuzuordnen` + : 'Bankverbindung unterbrochen. Bitte einen Admin bitten, sie wieder zu verbinden, um den Beleg zuzuordnen.'; } if (!isTransactionOlderThan7Days) { return isAdmin diff --git a/src/languages/en.ts b/src/languages/en.ts index e36d60e042d2..979fb2eed6f7 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -6795,12 +6795,14 @@ const translations = { }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Review required', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return "Can't auto-match receipt due to broken bank connection"; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { - return isAdmin ? `Can't auto-match receipt due to broken bank connection which ${email} needs to fix` : "Can't auto-match receipt due to broken bank connection"; + return isAdmin + ? `Bank connection broken. Reconnect to match receipt` + : 'Bank connection broken. Ask an admin to reconnect to match receipt.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Ask ${member} to mark as a cash or wait 7 days and try again` : 'Awaiting merge with card transaction.'; diff --git a/src/languages/es.ts b/src/languages/es.ts index 5cfea8155bb0..467a2154af7a 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1,6 +1,7 @@ import {CONST as COMMON_CONST} from 'expensify-common'; import CONST from '@src/CONST'; import type en from './en'; +import type {ViolationsRterParams} from './params'; import type {TranslationDeepObject} from './types'; /* eslint-disable max-len */ @@ -6924,14 +6925,14 @@ ${amount} para ${merchant} - ${date}`, }, customRules: ({message}) => message, reviewRequired: 'Revisión requerida', - rter: ({brokenBankConnection, isAdmin, email, isTransactionOlderThan7Days, member, rterType}) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'No se puede emparejar automáticamente el recibo debido a una conexión bancaria interrumpida.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `No se puede adjuntar recibo debido a un problema con la conexión a tu banco que ${email} necesita arreglar` - : 'No se puede adjuntar recibo debido a un problema con la conexión a tu banco'; + ? `Conexión bancaria interrumpida. Vuelve a conectarte para emparejar el recibo` + : 'Conexión bancaria interrumpida. Pide a un administrador que la vuelva a conectar para emparejar el recibo.'; } if (!isTransactionOlderThan7Days) { return isAdmin diff --git a/src/languages/fr.ts b/src/languages/fr.ts index d210f95c4d07..5a72824a6834 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -6836,14 +6836,14 @@ ${amount} pour ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Examen requis', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return "Impossible de faire correspondre automatiquement le reçu en raison d'une connexion bancaire défectueuse."; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Impossible de faire correspondre automatiquement le reçu en raison d'une connexion bancaire défectueuse que ${email} doit corriger.` - : "Impossible de faire correspondre automatiquement le reçu en raison d'une connexion bancaire défectueuse."; + ? `Connexion bancaire interrompue. Reconnecter pour associer le reçu` + : 'Connexion bancaire interrompue. Demandez à un administrateur de la reconnecter pour associer le reçu.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Demandez à ${member} de marquer comme espèce ou attendez 7 jours et réessayez` : 'En attente de fusion avec la transaction par carte.'; diff --git a/src/languages/it.ts b/src/languages/it.ts index 30d094b3fbdd..d9c067aa0f84 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -6844,14 +6844,14 @@ ${amount} per ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Revisione richiesta', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'Impossibile associare automaticamente la ricevuta a causa di una connessione bancaria interrotta.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Impossibile abbinare automaticamente la ricevuta a causa di una connessione bancaria interrotta che ${email} deve risolvere.` - : 'Impossibile associare automaticamente la ricevuta a causa di una connessione bancaria interrotta.'; + ? `Connessione bancaria interrotta. Riconnetti per abbinarla alla ricevuta` + : 'Connessione bancaria interrotta. Chiedi a un amministratore di riconnetterla per abbinare la ricevuta.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Chiedi a ${member} di contrassegnarlo come contante o attendi 7 giorni e riprova` : 'In attesa di unione con la transazione della carta.'; diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 3760ef0ee3fb..c3d2591057f7 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -6777,12 +6777,14 @@ ${date} - ${merchant}に${amount}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'レビューが必要です', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return '銀行接続が切れているため、領収書を自動照合できません。'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { - return isAdmin ? `${email}が修正する必要がある銀行接続の問題のため、領収書を自動マッチングできません。` : '銀行接続が切れているため、領収書を自動照合できません。'; + return isAdmin + ? `銀行接続が切断されています。再接続して領収書を照合してください` + : '銀行接続が切断されています。領収書を照合するには管理者に再接続を依頼してください。'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `${member}に現金としてマークするように依頼するか、7日間待って再試行してください。` : 'カード取引とのマージを待機中。'; diff --git a/src/languages/nl.ts b/src/languages/nl.ts index be0a042fbcfc..46395f99fa9c 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -6826,14 +6826,14 @@ ${amount} voor ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Beoordeling vereist', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'Kan bon niet automatisch koppelen vanwege verbroken bankverbinding.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Kan ontvangst niet automatisch koppelen vanwege een verbroken bankverbinding die ${email} moet herstellen.` - : 'Kan bon niet automatisch koppelen vanwege verbroken bankverbinding.'; + ? `Bankverbinding verbroken. Opnieuw verbinden om bon te koppelen` + : 'Bankverbinding verbroken. Vraag een beheerder om opnieuw te verbinden om de bon te koppelen.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Vraag ${member} om het als contant te markeren of wacht 7 dagen en probeer het opnieuw.` : 'In afwachting van samenvoeging met kaarttransactie.'; diff --git a/src/languages/params.ts b/src/languages/params.ts index 6ee4cffa34ff..752a7f7d81ba 100644 --- a/src/languages/params.ts +++ b/src/languages/params.ts @@ -326,10 +326,10 @@ type ViolationsCustomRulesParams = {message: string}; type ViolationsRterParams = { brokenBankConnection: boolean; isAdmin: boolean; - email?: string; isTransactionOlderThan7Days: boolean; member?: string; rterType?: ValueOf; + companyCardPageURL?: string; }; type ViolationsTagOutOfPolicyParams = {tagName?: string} | undefined; diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 0ba0a7a2a9cf..6d970b38ae1f 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -6813,14 +6813,14 @@ ${amount} dla ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Wymagana recenzja', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'Nie można automatycznie dopasować paragonu z powodu przerwanego połączenia z bankiem.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Nie można automatycznie dopasować paragonu z powodu zerwanego połączenia z bankiem, które ${email} musi naprawić.` - : 'Nie można automatycznie dopasować paragonu z powodu przerwanego połączenia z bankiem.'; + ? `Połączenie bankowe zostało przerwane. Połącz ponownie, aby dopasować paragon` + : 'Połączenie bankowe zostało przerwane. Poproś administratora o ponowne połączenie, aby dopasować paragon.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Poproś ${member}, aby oznaczył jako gotówkę lub poczekaj 7 dni i spróbuj ponownie.` : 'Oczekiwanie na połączenie z transakcją kartową.'; diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 0aefae6e26d8..3d9a7c84e7f5 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -6826,14 +6826,14 @@ ${amount} para ${merchant} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: 'Revisão necessária', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return 'Não é possível associar automaticamente o recibo devido a uma conexão bancária interrompida.'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { return isAdmin - ? `Não é possível associar automaticamente o recibo devido a uma conexão bancária interrompida que ${email} precisa corrigir.` - : 'Não é possível associar automaticamente o recibo devido a uma conexão bancária interrompida.'; + ? `Conexão bancária interrompida. Reconectar para associar o recibo` + : 'Conexão bancária interrompida. Peça a um administrador para reconectar e associar o recibo.'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `Peça a ${member} para marcar como dinheiro ou espere 7 dias e tente novamente.` : 'Aguardando a fusão com a transação do cartão.'; diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index c59c3511e9d8..2d6b7fe45067 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -6679,12 +6679,12 @@ ${merchant}的${amount} - ${date}`, }, customRules: ({message}: ViolationsCustomRulesParams) => message, reviewRequired: '需要审核', - rter: ({brokenBankConnection, email, isAdmin, isTransactionOlderThan7Days, member, rterType}: ViolationsRterParams) => { + rter: ({brokenBankConnection, isAdmin, isTransactionOlderThan7Days, member, rterType, companyCardPageURL}: ViolationsRterParams) => { if (rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530) { return '由于银行连接中断,无法自动匹配收据。'; } if (brokenBankConnection || rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION) { - return isAdmin ? `由于银行连接中断,无法自动匹配收据,需要${email}进行修复。` : '由于需要修复的银行连接中断,无法自动匹配收据。'; + return isAdmin ? `银行连接已中断。重新连接以匹配收据` : '银行连接已中断。请联系管理员重新连接以匹配收据。'; } if (!isTransactionOlderThan7Days) { return isAdmin ? `请${member}标记为现金,或等待7天后再试一次。` : '正在等待与卡交易合并。'; diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index 9dcb31f243d5..f4d023314fd7 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -468,11 +468,10 @@ const ViolationsUtils = { * possible values could be either translation keys that resolve to strings or translation keys that resolve to * functions. */ - getViolationTranslation(violation: TransactionViolation, translate: LocaleContextProps['translate'], canEdit = true, tags?: PolicyTagLists): string { + getViolationTranslation(violation: TransactionViolation, translate: LocaleContextProps['translate'], canEdit = true, tags?: PolicyTagLists, companyCardPageURL?: string): string { const { brokenBankConnection = false, isAdmin = false, - email, isTransactionOlderThan7Days = false, member, category, @@ -547,10 +546,10 @@ const ViolationsUtils = { return translate('violations.rter', { brokenBankConnection, isAdmin, - email, isTransactionOlderThan7Days, member, rterType, + companyCardPageURL, }); case 'smartscanFailed': return translate('violations.smartscanFailed', {canEdit}); @@ -595,6 +594,7 @@ const ViolationsUtils = { missingFieldError?: string, transactionThreadActions?: ReportAction[], tags?: PolicyTagLists, + companyCardPageURL?: string, ): string { const errorMessages = extractErrorMessages(transaction?.errors ?? {}, transactionThreadActions?.filter((e) => !!e.errors) ?? [], translate); @@ -604,7 +604,7 @@ const ViolationsUtils = { // Some violations end with a period already so lets make sure the connected messages have only single period between them // and end with a single dot. ...transactionViolations.map((violation) => { - const message = ViolationsUtils.getViolationTranslation(violation, translate, true, tags); + const message = ViolationsUtils.getViolationTranslation(violation, translate, true, tags, companyCardPageURL); if (!message) { return; } diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 1139c9bb8081..02d605138b94 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -670,11 +670,14 @@ const brokenCardConnection530Violation: TransactionViolation = { describe('getViolationTranslation', () => { it('should return the correct message for broken card connection violation', () => { + const testPolicyID = 'test-policy-123'; + const companyCardPageURL = `workspaces/${testPolicyID}/company-cards`; const brokenCardConnectionViolationExpected = translateLocal('violations.rter', { brokenBankConnection: true, isAdmin: true, rterType: CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION, isTransactionOlderThan7Days: false, + companyCardPageURL, }); expect(ViolationsUtils.getViolationTranslation(brokenCardConnectionViolation, translateLocal)).toBe(brokenCardConnectionViolationExpected); const brokenCardConnection530ViolationExpected = translateLocal('violations.rter', { @@ -682,6 +685,7 @@ describe('getViolationTranslation', () => { isAdmin: false, rterType: CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530, isTransactionOlderThan7Days: false, + companyCardPageURL, }); expect(ViolationsUtils.getViolationTranslation(brokenCardConnection530Violation, translateLocal)).toBe(brokenCardConnection530ViolationExpected); });