From d6a5c92d16628a7b7306943f8eac73a1c469d4cd Mon Sep 17 00:00:00 2001 From: Szymon Zalarski Date: Thu, 5 Mar 2026 06:59:13 +0100 Subject: [PATCH 1/2] Refactor transaction type handling to use a single card parameter instead of card list. Update TypeCell and related tests accordingly. --- .../TransactionItemRow/DataCells/TypeCell.tsx | 6 ++++-- src/libs/TransactionUtils/index.ts | 9 ++++----- tests/unit/TransactionUtilsTest.ts | 18 +++++++----------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/components/TransactionItemRow/DataCells/TypeCell.tsx b/src/components/TransactionItemRow/DataCells/TypeCell.tsx index 1908787f47f0..0213766e2996 100644 --- a/src/components/TransactionItemRow/DataCells/TypeCell.tsx +++ b/src/components/TransactionItemRow/DataCells/TypeCell.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import type {OnyxEntry} from 'react-native-onyx'; import Icon from '@components/Icon'; import TextWithTooltip from '@components/TextWithTooltip'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; @@ -10,6 +11,7 @@ import {getExpenseTypeTranslationKey, getTransactionType, isExpensifyCardTransac import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {CardList} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type TransactionDataCellProps from './TransactionDataCellProps'; @@ -31,10 +33,10 @@ const getTypeIcon = (icons: Record<'Car' | 'CreditCard' | 'Cash' | 'Clock' | 'Ca function TypeCell({transactionItem, shouldUseNarrowLayout, shouldShowTooltip}: TransactionDataCellProps) { const {translate} = useLocalize(); - const [cardList] = useOnyx(ONYXKEYS.CARD_LIST); + const [card] = useOnyx(ONYXKEYS.CARD_LIST, {selector: (cardList: OnyxEntry) => (transactionItem.cardID ? cardList?.[transactionItem.cardID] : undefined)}); const theme = useTheme(); const expensifyIcons = useMemoizedLazyExpensifyIcons(['Car', 'CreditCard', 'CreditCardHourglass', 'Cash', 'Clock', 'CalendarSolid']); - const type = getTransactionType(transactionItem, cardList); + const type = getTransactionType(transactionItem, card); const isPendingExpensifyCardTransaction = isExpensifyCardTransaction(transactionItem) && isPending(transactionItem); const typeIcon = isPendingExpensifyCardTransaction ? expensifyIcons.CreditCardHourglass : getTypeIcon(expensifyIcons, type); const typeText = isPendingExpensifyCardTransaction ? 'iou.pending' : getExpenseTypeTranslationKey(type); diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 1c589ffd34c1..f788e8af7199 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -53,7 +53,7 @@ import IntlStore from '@src/languages/IntlStore'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import type { - CardList, + Card, OnyxInputOrEntry, Policy, PolicyCategories, @@ -332,10 +332,10 @@ function getExpenseType(transaction: OnyxEntry): ValueOf, cardList?: CardList): ValueOf { +function getTransactionType(transaction: OnyxEntry, card?: Card): ValueOf { if (isDistanceRequest(transaction)) { return CONST.SEARCH.TRANSACTION_TYPE.DISTANCE; } @@ -352,8 +352,7 @@ function getTransactionType(transaction: OnyxEntry, cardList?: Card return CONST.SEARCH.TRANSACTION_TYPE.CARD; } - const cardID = transaction?.cardID; - if (cardID && cardList?.[cardID]?.cardName === CONST.COMPANY_CARDS.CARD_NAME.CASH) { + if (card?.cardName === CONST.COMPANY_CARDS.CARD_NAME.CASH) { return CONST.SEARCH.TRANSACTION_TYPE.CASH; } diff --git a/tests/unit/TransactionUtilsTest.ts b/tests/unit/TransactionUtilsTest.ts index 587a78962ebc..a401f4f32828 100644 --- a/tests/unit/TransactionUtilsTest.ts +++ b/tests/unit/TransactionUtilsTest.ts @@ -7,8 +7,7 @@ import IntlStore from '@src/languages/IntlStore'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Attendee} from '@src/types/onyx/IOU'; import * as TransactionUtils from '../../src/libs/TransactionUtils'; -import type {Policy, Report, Transaction} from '../../src/types/onyx'; -import type {CardList} from '../../src/types/onyx/Card'; +import type {Card, Policy, Report, Transaction} from '../../src/types/onyx'; import createRandomPolicy, {createCategoryTaxExpenseRules} from '../utils/collections/policies'; import {createRandomReport} from '../utils/collections/reports'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; @@ -424,18 +423,15 @@ describe('TransactionUtils', () => { expect(TransactionUtils.getTransactionType(transaction)).toBe(CONST.SEARCH.TRANSACTION_TYPE.PER_DIEM); }); - it('returns cash when the transaction cardID maps to a cash card in the card list', () => { - const cardID = 101; - const cardList = { - [cardID]: { - cardName: '__CASH__', - }, - } as unknown as CardList; + it('returns cash when the card has a cash card name', () => { + const card = { + cardName: CONST.COMPANY_CARDS.CARD_NAME.CASH, + } as Card; const transaction = generateTransaction({ - cardID, + cardID: 101, }); - expect(TransactionUtils.getTransactionType(transaction, cardList)).toBe(CONST.SEARCH.TRANSACTION_TYPE.CASH); + expect(TransactionUtils.getTransactionType(transaction, card)).toBe(CONST.SEARCH.TRANSACTION_TYPE.CASH); }); it('returns cash when the transaction card name includes the cash card name substring', () => { From ac02aa75dbe2e93f8e33a598066263119f31c529 Mon Sep 17 00:00:00 2001 From: Szymon Zalarski Date: Thu, 5 Mar 2026 07:52:26 +0100 Subject: [PATCH 2/2] PR fixes --- src/components/TransactionItemRow/DataCells/TypeCell.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/TransactionItemRow/DataCells/TypeCell.tsx b/src/components/TransactionItemRow/DataCells/TypeCell.tsx index 0213766e2996..1f36a6c84443 100644 --- a/src/components/TransactionItemRow/DataCells/TypeCell.tsx +++ b/src/components/TransactionItemRow/DataCells/TypeCell.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; import Icon from '@components/Icon'; import TextWithTooltip from '@components/TextWithTooltip'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; @@ -11,7 +10,6 @@ import {getExpenseTypeTranslationKey, getTransactionType, isExpensifyCardTransac import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {CardList} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type TransactionDataCellProps from './TransactionDataCellProps'; @@ -33,7 +31,7 @@ const getTypeIcon = (icons: Record<'Car' | 'CreditCard' | 'Cash' | 'Clock' | 'Ca function TypeCell({transactionItem, shouldUseNarrowLayout, shouldShowTooltip}: TransactionDataCellProps) { const {translate} = useLocalize(); - const [card] = useOnyx(ONYXKEYS.CARD_LIST, {selector: (cardList: OnyxEntry) => (transactionItem.cardID ? cardList?.[transactionItem.cardID] : undefined)}); + const [card] = useOnyx(ONYXKEYS.CARD_LIST, {selector: (cardList) => (transactionItem.cardID ? cardList?.[transactionItem.cardID] : undefined)}); const theme = useTheme(); const expensifyIcons = useMemoizedLazyExpensifyIcons(['Car', 'CreditCard', 'CreditCardHourglass', 'Cash', 'Clock', 'CalendarSolid']); const type = getTransactionType(transactionItem, card);