diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index b0efa98af423..55ad22ae6f2e 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -21,6 +21,7 @@ import useActiveRoute from '@hooks/useActiveRoute'; import useAncestors from '@hooks/useAncestors'; import useCardFeedErrors from '@hooks/useCardFeedErrors'; import useConfirmModal from '@hooks/useConfirmModal'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useEnvironment from '@hooks/useEnvironment'; @@ -127,6 +128,7 @@ function MoneyRequestReceiptView({ }: MoneyRequestReceiptViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const {convertToDisplayString} = useCurrencyListActions(); const {environmentURL} = useEnvironment(); const {shouldUseNarrowLayout, isInNarrowPaneModal} = useResponsiveLayout(); const {getReportRHPActiveRoute} = useActiveRoute(); @@ -293,6 +295,7 @@ function MoneyRequestReceiptView({ const violationMessage = ViolationsUtils.getViolationTranslation({ violation, translate, + convertToDisplayString, canEdit: isActionTakenByCurrentUser && isEditable, companyCardPageURL, connectionLink, @@ -308,7 +311,19 @@ function MoneyRequestReceiptView({ } } return [imageViolations, allViolations]; - }, [transactionViolations, translate, isActionTakenByCurrentUser, isEditable, companyCardPageURL, connectionLink, cardList, isMarkAsCash, routeDistanceMeters, distanceUnit]); + }, [ + transactionViolations, + translate, + convertToDisplayString, + isActionTakenByCurrentUser, + isEditable, + companyCardPageURL, + connectionLink, + cardList, + isMarkAsCash, + routeDistanceMeters, + distanceUnit, + ]); const receiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED); const itemizedReceiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.ITEMIZED_RECEIPT_REQUIRED); diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 0b5153099fb7..34a837ffefc1 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -636,6 +636,7 @@ function MoneyRequestView({ return ViolationsUtils.getViolationTranslation({ violation, translate, + convertToDisplayString, canEdit, companyCardPageURL, connectionLink, diff --git a/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx b/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx index 9e24adb4845e..cf769ec63d22 100644 --- a/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx +++ b/src/components/ReportActionItem/TransactionPreview/TransactionPreviewContent.tsx @@ -136,6 +136,7 @@ function TransactionPreviewContent({ ? ViolationsUtils.getViolationTranslation({ violation: firstViolation, translate, + convertToDisplayString, canEdit, companyCardPageURL, connectionLink, diff --git a/src/components/TransactionItemRow/TransactionItemRowRBR.tsx b/src/components/TransactionItemRow/TransactionItemRowRBR.tsx index 8e0826d56690..87c61fa22365 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 RenderHTML from '@components/RenderHTML'; import Text from '@components/Text'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useEnvironment from '@hooks/useEnvironment'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; @@ -52,6 +53,7 @@ type TransactionItemRowRBRProps = TransactionItemRowRBRInnerProps & { function TransactionItemRowRBRInner({transaction, violations, report, containerStyles, missingFieldError, shouldUseNarrowLayout}: TransactionItemRowRBRInnerProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const {convertToDisplayString} = useCurrencyListActions(); const theme = useTheme(); const {environmentURL} = useEnvironment(); const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transaction.reportID}`); @@ -72,6 +74,7 @@ function TransactionItemRowRBRInner({transaction, violations, report, containerS transaction, transactionViolations: isSettled(report) ? [] : (violations ?? []), translate, + convertToDisplayString, missingFieldError, transactionThreadActions: Object.values(transactionThreadActions ?? {}), tags: policyTags, diff --git a/src/components/ViolationMessages.tsx b/src/components/ViolationMessages.tsx index c9a558cfd511..3a5029865365 100644 --- a/src/components/ViolationMessages.tsx +++ b/src/components/ViolationMessages.tsx @@ -1,6 +1,7 @@ import React, {useMemo} from 'react'; import {View} from 'react-native'; import type {StyleProp, TextStyle, ViewStyle} from 'react-native'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -37,6 +38,7 @@ export default function ViolationMessages({ }: ViolationMessagesProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const {convertToDisplayString} = useCurrencyListActions(); const [cardList] = useOnyx(ONYXKEYS.CARD_LIST); const filteredViolations = useMemo(() => filterReceiptViolations(violations), [violations]); @@ -51,6 +53,7 @@ export default function ViolationMessages({ ViolationsUtils.getViolationTranslation({ violation, translate, + convertToDisplayString, canEdit, companyCardPageURL, connectionLink, @@ -61,7 +64,7 @@ export default function ViolationMessages({ }), ]; }), - [canEdit, translate, filteredViolations, companyCardPageURL, connectionLink, cardList, isMarkAsCash, routeDistanceMeters, distanceUnit], + [canEdit, translate, convertToDisplayString, filteredViolations, companyCardPageURL, connectionLink, cardList, isMarkAsCash, routeDistanceMeters, distanceUnit], ); return ( diff --git a/src/libs/DebugUtils.ts b/src/libs/DebugUtils.ts index 60add514f522..30153132ed4f 100644 --- a/src/libs/DebugUtils.ts +++ b/src/libs/DebugUtils.ts @@ -1328,6 +1328,8 @@ function validateTransactionViolationDraftProperty(key: keyof TransactionViolati rejectedBy: 'string', rejectReason: 'string', formattedLimit: 'string', + amount: 'number', + currency: 'string', surcharge: 'number', invoiceMarkup: 'number', maxAge: 'number', diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index 9d279e329c1a..b438876eb7bb 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -4,10 +4,10 @@ import reject from 'lodash/reject'; import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; +import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import {convertAttendeesToArray, getIsMissingAttendeesViolation} from '@libs/AttendeeUtils'; import {isPersonalCard} from '@libs/CardUtils'; import {getDecodedCategoryName, isCategoryMissing} from '@libs/CategoryUtils'; -import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; import {isReceiptError} from '@libs/ErrorUtils'; @@ -30,11 +30,13 @@ import type {Card, CardList, Policy, PolicyCategories, PolicyTagLists, PolicyTag import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Unit} from '@src/types/onyx/Policy'; import type {ReceiptError, ReceiptErrors} from '@src/types/onyx/Transaction'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type ViolationFixParams from './types'; type ViolationTranslationParams = { violation: TransactionViolation; translate: LocaleContextProps['translate']; + convertToDisplayString: CurrencyListActionsContextType['convertToDisplayString']; canEdit?: boolean; tags?: PolicyTagLists; companyCardPageURL?: string; @@ -586,7 +588,8 @@ const ViolationsUtils = { shouldShowCategoryItemizedReceiptRequiredViolation || !policy.maxExpenseAmountNoItemizedReceipt ? undefined : { - formattedLimit: CurrencyUtils.convertToDisplayString(policy.maxExpenseAmountNoItemizedReceipt, policy.outputCurrency, true), + amount: policy.maxExpenseAmountNoItemizedReceipt, + currency: policy.outputCurrency, }, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, @@ -608,7 +611,8 @@ const ViolationsUtils = { shouldShowCategoryReceiptRequiredViolation || !policy.maxExpenseAmountNoReceipt ? undefined : { - formattedLimit: CurrencyUtils.convertToDisplayString(policy.maxExpenseAmountNoReceipt, policy.outputCurrency, true), + amount: policy.maxExpenseAmountNoReceipt, + currency: policy.outputCurrency, }, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, @@ -627,7 +631,8 @@ const ViolationsUtils = { newTransactionViolations.push({ name: shouldCategoryShowOverLimitViolation ? CONST.VIOLATIONS.OVER_CATEGORY_LIMIT : CONST.VIOLATIONS.OVER_LIMIT, data: { - formattedLimit: CurrencyUtils.convertAmountToDisplayString(shouldCategoryShowOverLimitViolation ? categoryOverLimit : policy.maxExpenseAmount, policy.outputCurrency), + amount: shouldCategoryShowOverLimitViolation ? categoryOverLimit : policy.maxExpenseAmount, + currency: policy.outputCurrency, }, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, @@ -638,7 +643,8 @@ const ViolationsUtils = { newTransactionViolations.push({ name: CONST.VIOLATIONS.OVER_TRIP_LIMIT, data: { - formattedLimit: CurrencyUtils.convertAmountToDisplayString(-updatedTransaction.amount, updatedTransaction.currency), + amount: -updatedTransaction.amount, + currency: updatedTransaction.currency, }, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, @@ -698,7 +704,7 @@ const ViolationsUtils = { * functions. */ getViolationTranslation(params: ViolationTranslationParams): string { - const {violation, translate, canEdit = true, tags, companyCardPageURL, connectionLink, card, isMarkAsCash, routeDistanceMeters, distanceUnit} = params; + const {violation, translate, convertToDisplayString, canEdit = true, tags, companyCardPageURL, connectionLink, card, isMarkAsCash, routeDistanceMeters, distanceUnit} = params; const { brokenBankConnection = false, isAdmin = false, @@ -706,6 +712,8 @@ const ViolationsUtils = { member, category, formattedLimit = '', + amount = 0, + currency = CONST.CURRENCY.USD, surcharge = 0, invoiceMarkup = 0, maxAge = 0, @@ -766,11 +774,11 @@ const ViolationsUtils = { case 'overAutoApprovalLimit': return translate('violations.overAutoApprovalLimit', formattedLimit); case 'overCategoryLimit': - return translate('violations.overCategoryLimit', formattedLimit); + return translate('violations.overCategoryLimit', convertToDisplayString(amount, currency)); case 'overLimit': - return translate('violations.overLimit', formattedLimit); + return translate('violations.overLimit', convertToDisplayString(amount, currency)); case 'overTripLimit': - return translate('violations.overTripLimit', formattedLimit); + return translate('violations.overTripLimit', convertToDisplayString(amount, currency)); case 'overLimitAttendee': return translate('violations.overLimitAttendee', formattedLimit); case 'perDayLimit': @@ -778,9 +786,9 @@ const ViolationsUtils = { case 'receiptNotSmartScanned': return translate('violations.receiptNotSmartScanned'); case 'receiptRequired': - return translate('violations.receiptRequired', formattedLimit, getDecodedCategoryName(category ?? '')); + return translate('violations.receiptRequired', !isEmptyObject(violation.data) ? convertToDisplayString(amount, currency) : undefined, getDecodedCategoryName(category ?? '')); case 'itemizedReceiptRequired': - return translate('violations.itemizedReceiptRequired', formattedLimit); + return translate('violations.itemizedReceiptRequired', !isEmptyObject(violation.data) ? convertToDisplayString(amount, currency) : undefined); case 'customRules': return translate('violations.customRules', message); case 'rter': { @@ -834,15 +842,11 @@ const ViolationsUtils = { } }, - // We have to use regex, because Violation limit is given in a inconvenient form: "$2,000.00" - getViolationAmountLimit(violation: TransactionViolation): number { - return Number(violation.data?.formattedLimit?.replace(CONST.VIOLATION_LIMIT_REGEX, '')); - }, - getRBRMessages({ transaction, transactionViolations, translate, + convertToDisplayString, missingFieldError, transactionThreadActions, tags, @@ -855,6 +859,7 @@ const ViolationsUtils = { transaction: Transaction; transactionViolations: TransactionViolation[]; translate: LocaleContextProps['translate']; + convertToDisplayString: CurrencyListActionsContextType['convertToDisplayString']; missingFieldError?: string; transactionThreadActions?: ReportAction[]; tags?: PolicyTagLists; @@ -878,6 +883,7 @@ const ViolationsUtils = { const message = ViolationsUtils.getViolationTranslation({ violation, translate, + convertToDisplayString, canEdit, tags, companyCardPageURL, diff --git a/src/libs/actions/IOU/UpdateMoneyRequest.ts b/src/libs/actions/IOU/UpdateMoneyRequest.ts index c7f94fb7fbd5..59ac861d0990 100644 --- a/src/libs/actions/IOU/UpdateMoneyRequest.ts +++ b/src/libs/actions/IOU/UpdateMoneyRequest.ts @@ -1427,7 +1427,7 @@ function getUpdateMoneyRequestParams(params: GetUpdateMoneyRequestParamsType): U // Update violation limit, if we modify attendees. The given limit value is for a single attendee, if we have multiple attendees we should multiply limit by attendee count const overLimitViolation = violations?.find((violation) => violation.name === 'overLimit'); if (overLimitViolation) { - const limitForSingleAttendee = ViolationsUtils.getViolationAmountLimit(overLimitViolation); + const limitForSingleAttendee = overLimitViolation.data?.amount ?? 0; if (limitForSingleAttendee * (transactionChanges?.attendees?.length ?? 1) > Math.abs(getAmount(transaction))) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/pages/home/YourSpendSection/CardRow.tsx b/src/pages/home/YourSpendSection/CardRow.tsx index 4ab91b777628..043c6e5e116b 100644 --- a/src/pages/home/YourSpendSection/CardRow.tsx +++ b/src/pages/home/YourSpendSection/CardRow.tsx @@ -4,12 +4,12 @@ import {View} from 'react-native'; import CardFeedIcon from '@components/CardFeedIcon'; import Icon from '@components/Icon'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useHover from '@hooks/useHover'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import {convertToDisplayString} from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; @@ -25,6 +25,7 @@ function CardRow({cardRow, wrapperStyle}: CardRowProps) { const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); + const {convertToDisplayString} = useCurrencyListActions(); const icons = useMemoizedLazyExpensifyIcons(['ArrowRight']); const {hovered, bind} = useHover(); const {onMouseEnter, onMouseLeave} = bind; diff --git a/src/pages/home/YourSpendSection/SpendSummaryRow.tsx b/src/pages/home/YourSpendSection/SpendSummaryRow.tsx index b35b5ed0bd60..10d448e71e29 100644 --- a/src/pages/home/YourSpendSection/SpendSummaryRow.tsx +++ b/src/pages/home/YourSpendSection/SpendSummaryRow.tsx @@ -5,10 +5,10 @@ import Icon from '@components/Icon'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import SkeletonRect from '@components/SkeletonRect'; import ItemListSkeletonView from '@components/Skeletons/ItemListSkeletonView'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import {convertToDisplayString} from '@libs/CurrencyUtils'; import variables from '@styles/variables'; import type IconAsset from '@src/types/utils/IconAsset'; import YOUR_SPEND_ROW_STATE from './const'; @@ -60,6 +60,7 @@ function SpendSummaryRow({state, testIDPrefix, description, totals, iconSrc, onP const styles = useThemeStyles(); const theme = useTheme(); const {shouldUseNarrowLayout} = useResponsiveLayout(); + const {convertToDisplayString} = useCurrencyListActions(); if (state === YOUR_SPEND_ROW_STATE.LOADING) { const horizontalPadding = shouldUseNarrowLayout ? SKELETON_NARROW_OFFSET_X : SKELETON_WIDE_OFFSET_X; diff --git a/src/types/onyx/TransactionViolation.ts b/src/types/onyx/TransactionViolation.ts index 9097a75d0f5b..6b667ea039d8 100644 --- a/src/types/onyx/TransactionViolation.ts +++ b/src/types/onyx/TransactionViolation.ts @@ -32,6 +32,12 @@ type TransactionViolationData = { /** Limit that the transaction violated */ formattedLimit?: string; + /** Currency of the transaction */ + currency?: string; + + /** Limit amount that the transaction violated */ + amount?: number; + /** Percentage amount of conversion surcharge applied to the transaction */ surcharge?: number; diff --git a/tests/unit/TransactionPreviewUtils.test.ts b/tests/unit/TransactionPreviewUtils.test.ts index a4b92de7b36c..2bdf6a25d52d 100644 --- a/tests/unit/TransactionPreviewUtils.test.ts +++ b/tests/unit/TransactionPreviewUtils.test.ts @@ -594,7 +594,7 @@ describe('TransactionPreviewUtils', () => { name: CONST.VIOLATIONS.ITEMIZED_RECEIPT_REQUIRED, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, - data: {formattedLimit: '$75.00'}, + data: {amount: 7500, currency: CONST.CURRENCY.USD}, }; const mockViolations = (count: number) => diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 3e7004653e96..820406b04f54 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -1,6 +1,6 @@ import {beforeEach} from '@jest/globals'; import Onyx from 'react-native-onyx'; -import {convertAmountToDisplayString} from '@libs/CurrencyUtils'; +import {convertToDisplayString} from '@libs/CurrencyUtils'; import {getTransactionViolations, hasWarningTypeViolation, isViolationDismissed} from '@libs/TransactionUtils'; import ViolationsUtils, {filterReceiptViolations, getIsViolationFixed} from '@libs/Violations/ViolationsUtils'; import CONST from '@src/CONST'; @@ -40,7 +40,8 @@ const receiptRequiredViolation = { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: convertAmountToDisplayString(CONST.POLICY.DEFAULT_MAX_AMOUNT_NO_RECEIPT), + amount: CONST.POLICY.DEFAULT_MAX_AMOUNT_NO_RECEIPT, + currency: CONST.CURRENCY.USD, }, }; @@ -56,7 +57,8 @@ const overLimitViolation = { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: convertAmountToDisplayString(CONST.POLICY.DEFAULT_MAX_EXPENSE_AMOUNT), + amount: CONST.POLICY.DEFAULT_MAX_EXPENSE_AMOUNT, + currency: CONST.CURRENCY.USD, }, }; @@ -65,7 +67,8 @@ const categoryOverLimitViolation = { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: convertAmountToDisplayString(CONST.POLICY.DEFAULT_MAX_EXPENSE_AMOUNT), + amount: CONST.POLICY.DEFAULT_MAX_EXPENSE_AMOUNT, + currency: CONST.CURRENCY.USD, }, }; @@ -74,7 +77,8 @@ const overTripLimitViolation = { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: convertAmountToDisplayString(400), + amount: 400, + currency: CONST.CURRENCY.USD, }, }; @@ -458,7 +462,7 @@ describe('getViolationsOnyxData', () => { policy.maxExpenseAmountNoItemizedReceipt = 7500; // $75.00 transaction.amount = -10000; // $100.00 const existingViolations: TransactionViolation[] = [ - {name: CONST.VIOLATIONS.ITEMIZED_RECEIPT_REQUIRED, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: {formattedLimit: '$50.00'}}, + {name: CONST.VIOLATIONS.ITEMIZED_RECEIPT_REQUIRED, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: {amount: 5000, currency: CONST.CURRENCY.USD}}, ]; // When violations are recalculated after the policy threshold changed @@ -468,7 +472,9 @@ describe('getViolationsOnyxData', () => { // Then the violation should have updated threshold data to reflect the current policy settings const itemizedViolation = violations.find((v: TransactionViolation) => v.name === CONST.VIOLATIONS.ITEMIZED_RECEIPT_REQUIRED); expect(itemizedViolation).toBeDefined(); - expect(itemizedViolation?.data?.formattedLimit).not.toBe('$50.00'); + expect(itemizedViolation?.data?.amount).toBe(7500); + expect(itemizedViolation?.data?.currency).toBe(CONST.CURRENCY.USD); + expect(itemizedViolation?.data?.amount).not.toBe(5000); }); it('should replace receiptRequired with itemizedReceiptRequired when category changes to always require itemized', () => { @@ -1532,7 +1538,9 @@ describe('getViolationTranslation', () => { const testPolicyID = 'test-policy-123'; const companyCardPageURL = `workspaces/${testPolicyID}/company-cards`; const brokenCardConnectionViolationExpected = translateLocal('violations.rter', true, true, false, undefined, CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION, companyCardPageURL); - expect(ViolationsUtils.getViolationTranslation({violation: brokenCardConnectionViolation, translate: translateLocal})).toBe(brokenCardConnectionViolationExpected); + expect(ViolationsUtils.getViolationTranslation({violation: brokenCardConnectionViolation, translate: translateLocal, convertToDisplayString})).toBe( + brokenCardConnectionViolationExpected, + ); const brokenCardConnection530ViolationExpected = translateLocal( 'violations.rter', true, @@ -1542,7 +1550,9 @@ describe('getViolationTranslation', () => { CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530, companyCardPageURL, ); - expect(ViolationsUtils.getViolationTranslation({violation: brokenCardConnection530Violation, translate: translateLocal})).toBe(brokenCardConnection530ViolationExpected); + expect(ViolationsUtils.getViolationTranslation({violation: brokenCardConnection530Violation, translate: translateLocal, convertToDisplayString})).toBe( + brokenCardConnection530ViolationExpected, + ); }); describe('increasedDistance violation', () => { @@ -1566,6 +1576,7 @@ describe('getViolationTranslation', () => { const result = ViolationsUtils.getViolationTranslation({ violation: increasedDistanceViolation, translate: translateLocal, + convertToDisplayString, canEdit: true, routeDistanceMeters, distanceUnit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS, @@ -1577,6 +1588,7 @@ describe('getViolationTranslation', () => { const result = ViolationsUtils.getViolationTranslation({ violation: increasedDistanceViolation, translate: translateLocal, + convertToDisplayString, canEdit: true, routeDistanceMeters, distanceUnit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, @@ -1588,6 +1600,7 @@ describe('getViolationTranslation', () => { const result = ViolationsUtils.getViolationTranslation({ violation: increasedDistanceViolation, translate: translateLocal, + convertToDisplayString, canEdit: true, routeDistanceMeters: 0, distanceUnit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS, @@ -1599,6 +1612,7 @@ describe('getViolationTranslation', () => { const result = ViolationsUtils.getViolationTranslation({ violation: increasedDistanceViolation, translate: translateLocal, + convertToDisplayString, canEdit: true, distanceUnit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS, }); @@ -1609,6 +1623,7 @@ describe('getViolationTranslation', () => { const result = ViolationsUtils.getViolationTranslation({ violation: increasedDistanceViolation, translate: translateLocal, + convertToDisplayString, canEdit: true, routeDistanceMeters, }); @@ -1644,6 +1659,7 @@ describe('getRBRMessages', () => { transaction: mockTransaction, transactionViolations: mockViolations, translate: translateLocal, + convertToDisplayString, missingFieldError, transactionThreadActions: [], }); @@ -1653,7 +1669,13 @@ describe('getRBRMessages', () => { }); it('should filter out empty strings', () => { - const result = ViolationsUtils.getRBRMessages({transaction: mockTransaction, transactionViolations: mockViolations, translate: translateLocal, transactionThreadActions: []}); + const result = ViolationsUtils.getRBRMessages({ + transaction: mockTransaction, + transactionViolations: mockViolations, + translate: translateLocal, + convertToDisplayString, + transactionThreadActions: [], + }); const expectedResult = `${translateLocal('violations.missingCategory')}. ${translateLocal('violations.missingTag')}.`; expect(result).toBe(expectedResult); @@ -2081,7 +2103,8 @@ describe('filterReceiptViolations', () => { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: '$75.00', + amount: 7500, + currency: CONST.CURRENCY.USD, }, }; @@ -2090,7 +2113,8 @@ describe('filterReceiptViolations', () => { type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true, data: { - formattedLimit: '$25.00', + amount: 2500, + currency: CONST.CURRENCY.USD, }, }; diff --git a/tests/unit/useViolationsTest.ts b/tests/unit/useViolationsTest.ts index 6bbc8ac488b9..46744390d4c9 100644 --- a/tests/unit/useViolationsTest.ts +++ b/tests/unit/useViolationsTest.ts @@ -339,7 +339,7 @@ describe('useViolations', () => { { name: CONST.VIOLATIONS.OVER_CATEGORY_LIMIT, type: CONST.VIOLATION_TYPES.VIOLATION, - data: {formattedLimit: '$1,000 USD', category: 'Travel'}, + data: {amount: 100000, currency: CONST.CURRENCY.USD, category: 'Travel'}, }, ]; @@ -349,7 +349,7 @@ describe('useViolations', () => { // Then all original data should be preserved for the UI to display detailed error messages expect(amountViolations).toHaveLength(1); - expect(amountViolations.at(0)?.data).toEqual({formattedLimit: '$1,000 USD', category: 'Travel'}); + expect(amountViolations.at(0)?.data).toEqual({amount: 100000, currency: CONST.CURRENCY.USD, category: 'Travel'}); }); }); });