diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 092dd7486741..e9c6ffdd8acc 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -5314,6 +5314,35 @@ const CONST = { USAA: 'usaa', }, + /** + * Bank account names (user friendly) + */ + get BANK_NAMES_USER_FRIENDLY() { + return { + [this.BANK_NAMES.EXPENSIFY]: 'Expensify', + [this.BANK_NAMES.AMERICAN_EXPRESS]: 'American Express', + [this.BANK_NAMES.BANK_OF_AMERICA]: 'Bank of America', + [this.BANK_NAMES.BB_T]: 'Truist', + [this.BANK_NAMES.CAPITAL_ONE]: 'Capital One', + [this.BANK_NAMES.CHASE]: 'Chase', + [this.BANK_NAMES.CHARLES_SCHWAB]: 'Charles Schwab', + [this.BANK_NAMES.CITIBANK]: 'Citibank', + [this.BANK_NAMES.CITIZENS_BANK]: 'Citizens', + [this.BANK_NAMES.DISCOVER]: 'Discover', + [this.BANK_NAMES.FIDELITY]: 'Fidelity', + [this.BANK_NAMES.GENERIC_BANK]: 'Bank', + [this.BANK_NAMES.HUNTINGTON_BANK]: 'Huntington', + [this.BANK_NAMES.HUNTINGTON_NATIONAL]: 'Huntington National', + [this.BANK_NAMES.NAVY_FEDERAL_CREDIT_UNION]: 'Navy Federal Credit Union', + [this.BANK_NAMES.PNC]: 'PNC', + [this.BANK_NAMES.REGIONS_BANK]: 'Regions', + [this.BANK_NAMES.SUNTRUST]: 'SunTrust', + [this.BANK_NAMES.TD_BANK]: 'TD Bank', + [this.BANK_NAMES.US_BANK]: 'U.S. Bank', + [this.BANK_NAMES.USAA]: 'USAA', + }; + }, + /** * Constants for maxToRenderPerBatch parameter that is used for FlatList or SectionList. This controls the amount of items rendered per batch, which is the next chunk of items * rendered on every scroll. @@ -6391,6 +6420,7 @@ const CONST = { ASSIGNEE: 'assignee', IN: 'in', CARD: 'card', + WITHDRAWAL_ID: 'withdrawalID', }, SYNTAX_OPERATORS: { AND: 'and', diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportTableHeader.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTableHeader.tsx index e76a914f35cf..9b696a4d4211 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportTableHeader.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportTableHeader.tsx @@ -31,6 +31,7 @@ const shouldShowColumnConfig: Record false, [CONST.SEARCH.TABLE_COLUMNS.ASSIGNEE]: () => false, [CONST.SEARCH.TABLE_COLUMNS.CARD]: () => false, + [CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID]: () => false, }; const columnConfig: ColumnConfig[] = [ diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index d094bbd96566..d282ca53a442 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -41,6 +41,7 @@ import { isTransactionGroupListItemType, isTransactionListItemType, isTransactionMemberGroupListItemType, + isTransactionWithdrawalIDGroupListItemType, shouldShowEmptyState, shouldShowYear as shouldShowYearUtil, } from '@libs/SearchUIUtils'; @@ -559,6 +560,10 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS return; } + if (isTransactionWithdrawalIDGroupListItemType(item)) { + return; + } + const isFromSelfDM = item.reportID === CONST.REPORT.UNREPORTED_REPORT_ID; const isTransactionItem = isTransactionListItemType(item); @@ -630,7 +635,13 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS const isChat = type === CONST.SEARCH.DATA_TYPES.CHAT; const isTask = type === CONST.SEARCH.DATA_TYPES.TASK; - const canSelectMultiple = !isChat && !isTask && (!isSmallScreenWidth || isMobileSelectionModeEnabled) && groupBy !== CONST.SEARCH.GROUP_BY.FROM && groupBy !== CONST.SEARCH.GROUP_BY.CARD; + const canSelectMultiple = + !isChat && + !isTask && + (!isSmallScreenWidth || isMobileSelectionModeEnabled) && + groupBy !== CONST.SEARCH.GROUP_BY.FROM && + groupBy !== CONST.SEARCH.GROUP_BY.CARD && + groupBy !== CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID; const ListItem = getListItem(type, status, groupBy); const sortedSelectedData = useMemo( () => diff --git a/src/components/SelectionList/Search/TransactionGroupListItem.tsx b/src/components/SelectionList/Search/TransactionGroupListItem.tsx index c11569db81b8..9db2f6da979f 100644 --- a/src/components/SelectionList/Search/TransactionGroupListItem.tsx +++ b/src/components/SelectionList/Search/TransactionGroupListItem.tsx @@ -13,6 +13,7 @@ import type { TransactionListItemType, TransactionMemberGroupListItemType, TransactionReportGroupListItemType, + TransactionWithdrawalIDGroupListItemType, } from '@components/SelectionList/types'; import Text from '@components/Text'; import TransactionItemRow from '@components/TransactionItemRow'; @@ -32,6 +33,7 @@ import ROUTES from '@src/ROUTES'; import CardListItemHeader from './CardListItemHeader'; import MemberListItemHeader from './MemberListItemHeader'; import ReportListItemHeader from './ReportListItemHeader'; +import WithdrawalIDListItemHeader from './WithdrawalIDListItemHeader'; function TransactionGroupListItem({ item, @@ -138,8 +140,13 @@ function TransactionGroupListItem({ /> ), [CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: ( - // Will be implemented as part of https://github.com/Expensify/App/pull/66078 - + ), }; diff --git a/src/components/SelectionList/Search/WithdrawalIDListItemHeader.tsx b/src/components/SelectionList/Search/WithdrawalIDListItemHeader.tsx new file mode 100644 index 000000000000..5448be3901f6 --- /dev/null +++ b/src/components/SelectionList/Search/WithdrawalIDListItemHeader.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import {View} from 'react-native'; +import Checkbox from '@components/Checkbox'; +import Icon from '@components/Icon'; +import getBankIcon from '@components/Icon/BankIcons'; +import type {ListItem, TransactionWithdrawalIDGroupListItemType} from '@components/SelectionList/types'; +import TextWithTooltip from '@components/TextWithTooltip'; +import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useThemeStyles from '@hooks/useThemeStyles'; +import DateUtils from '@libs/DateUtils'; +import CONST from '@src/CONST'; +import ActionCell from './ActionCell'; +import TotalCell from './TotalCell'; + +type WithdrawalIDListItemHeaderProps = { + /** The withdrawal ID currently being looked at */ + withdrawalID: TransactionWithdrawalIDGroupListItemType; + + /** Callback to fire when the item is pressed */ + onSelectRow: (item: TItem) => void; + + /** Callback to fire when a checkbox is pressed */ + onCheckboxPress?: (item: TItem) => void; + + /** Whether this section items disabled for selection */ + isDisabled?: boolean | null; + + /** Whether selecting multiple transactions at once is allowed */ + canSelectMultiple: boolean | undefined; +}; + +function WithdrawalIDListItemHeader({ + withdrawalID: withdrawalIDItem, + onSelectRow, + onCheckboxPress, + isDisabled, + canSelectMultiple, +}: WithdrawalIDListItemHeaderProps) { + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const {translate} = useLocalize(); + const {isLargeScreenWidth} = useResponsiveLayout(); + const {icon, iconSize, iconStyles} = getBankIcon({bankName: withdrawalIDItem.bankName, styles}); + const formattedBankName = CONST.BANK_NAMES_USER_FRIENDLY[withdrawalIDItem.bankName]; + const formattedWithdrawalDate = DateUtils.formatWithUTCTimeZone( + withdrawalIDItem.debitPosted, + DateUtils.doesDateBelongToAPastYear(withdrawalIDItem.debitPosted) ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, + ); + const shouldShowAction = isLargeScreenWidth; + + return ( + + + + {!!canSelectMultiple && ( + onCheckboxPress?.(withdrawalIDItem as unknown as TItem)} + isChecked={withdrawalIDItem.isSelected} + disabled={!!isDisabled || withdrawalIDItem.isDisabledCheckbox} + accessibilityLabel={translate('common.select')} + /> + )} + + + + + + + + + + + + {shouldShowAction && ( + + onSelectRow(withdrawalIDItem as unknown as TItem)} + isSelected={withdrawalIDItem.isSelected} + /> + + )} + + + ); +} + +WithdrawalIDListItemHeader.displayName = 'WithdrawalIDListItemHeader'; + +export default WithdrawalIDListItemHeader; diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx index b0497fb49b7a..0ca5546bde30 100644 --- a/src/components/SelectionList/SearchTableHeader.tsx +++ b/src/components/SelectionList/SearchTableHeader.tsx @@ -34,6 +34,7 @@ const shouldShowColumnConfig: Record true, [CONST.SEARCH.TABLE_COLUMNS.IN]: () => true, [CONST.SEARCH.TABLE_COLUMNS.CARD]: () => false, + [CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID]: () => false, // This column is never displayed on Search [CONST.REPORT.TRANSACTION_LIST.COLUMNS.COMMENTS]: () => false, }; @@ -81,6 +82,10 @@ const expenseHeaders: SearchColumnConfig[] = [ columnName: CONST.SEARCH.TABLE_COLUMNS.TAG, translationKey: 'common.tag', }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID, + translationKey: 'common.withdrawalID', + }, { columnName: CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT, translationKey: 'common.tax', @@ -178,6 +183,9 @@ function SearchTableHeader({ if (groupBy === CONST.SEARCH.GROUP_BY.CARD) { return columnName === CONST.SEARCH.TABLE_COLUMNS.CARD || columnName === CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT || columnName === CONST.SEARCH.TABLE_COLUMNS.ACTION; } + if (groupBy === CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID) { + return columnName === CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID || columnName === CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT || columnName === CONST.SEARCH.TABLE_COLUMNS.ACTION; + } const shouldShowFun = shouldShowColumnConfig[columnName]; return shouldShowFun(data, metadata); diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 0c8cc8429cb7..7d6b215589d3 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -348,7 +348,7 @@ type TransactionMemberGroupListItemType = TransactionGroupListItemType & {groupe type TransactionCardGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.CARD} & SearchPersonalDetails & SearchCardGroup; -type TransactionWithdrawalIDGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID} & SearchPersonalDetails & SearchWithdrawalIDGroup; +type TransactionWithdrawalIDGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID} & SearchWithdrawalIDGroup; type ListItemProps = CommonListItemProps & { /** The section list item */ diff --git a/src/languages/de.ts b/src/languages/de.ts index 24075db4e304..6742b3088bf0 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -587,6 +587,7 @@ const translations = { network: 'Netzwerk', reportID: 'Berichts-ID', longID: 'Lange ID', + withdrawalID: 'Auszahlungs-ID', bankAccounts: 'Bankkonten', chooseFile: 'Datei auswählen', chooseFiles: 'Dateien auswählen', diff --git a/src/languages/en.ts b/src/languages/en.ts index 6b3aa34a76f3..f915e36ef6a3 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -579,6 +579,7 @@ const translations = { network: 'Network', reportID: 'Report ID', longID: 'Long ID', + withdrawalID: 'Withdrawal ID', bankAccounts: 'Bank accounts', chooseFile: 'Choose file', chooseFiles: 'Choose files', diff --git a/src/languages/es.ts b/src/languages/es.ts index 2d5402374455..fd1975473864 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -571,6 +571,7 @@ const translations = { network: 'La red', reportID: 'ID del informe', longID: 'ID largo', + withdrawalID: 'ID de retiro', bankAccounts: 'Cuentas bancarias', chooseFile: 'Elegir archivo', chooseFiles: 'Elegir archivos', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 44204f4c8b12..a8ac17a57a82 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -587,6 +587,7 @@ const translations = { network: 'Réseau', reportID: 'ID du rapport', longID: 'ID long', + withdrawalID: 'ID de retrait', bankAccounts: 'Comptes bancaires', chooseFile: 'Choisir un fichier', chooseFiles: 'Choisir des fichiers', diff --git a/src/languages/it.ts b/src/languages/it.ts index da0c3fd5da1a..8b47c9f6f463 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -587,6 +587,7 @@ const translations = { network: 'Rete', reportID: 'ID Rapporto', longID: 'ID lungo', + withdrawalID: 'ID di prelievo', bankAccounts: 'Conti bancari', chooseFile: 'Scegli file', chooseFiles: 'Scegli file', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 3a839d07010c..827f1c861595 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -587,6 +587,7 @@ const translations = { network: 'ネットワーク', reportID: 'レポートID', longID: 'Long ID', + withdrawalID: '出金ID', bankAccounts: '銀行口座', chooseFile: 'ファイルを選択', chooseFiles: 'ファイルを選択', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 9f9dc1f9b1ac..e72380da6c6b 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -587,6 +587,7 @@ const translations = { network: 'Netwerk', reportID: 'Rapport-ID', longID: 'Lang ID', + withdrawalID: 'Opname-ID', bankAccounts: 'Bankrekeningen', chooseFile: 'Bestand kiezen', chooseFiles: 'Bestanden kiezen', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 7bbd38eb0e91..b5da0f8ff270 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -587,6 +587,7 @@ const translations = { network: 'Sieć', reportID: 'ID raportu', longID: 'Długi identyfikator', + withdrawalID: 'Identyfikator wypłaty', bankAccounts: 'Konta bankowe', chooseFile: 'Wybierz plik', chooseFiles: 'Wybierz pliki', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 344b3bd485f2..b1913dee50e2 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -588,6 +588,7 @@ const translations = { network: 'Network', reportID: 'ID do Relatório', longID: 'ID longo', + withdrawalID: 'ID de retirada', bankAccounts: 'Contas bancárias', chooseFile: 'Escolher arquivo', chooseFiles: 'Escolher arquivos', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 5e0f238759f2..a83cc4d59c4f 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -587,6 +587,7 @@ const translations = { network: '网络', reportID: '报告 ID', longID: 'Long ID', + withdrawalID: '提现ID', bankAccounts: '银行账户', chooseFile: '选择文件', chooseFiles: '选择文件', diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index d7c651300026..8c68d67bea8e 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -54,6 +54,7 @@ import type { SearchTask, SearchTransaction, SearchTransactionAction, + SearchWithdrawalIDGroup, } from '@src/types/onyx/SearchResults'; import type IconAsset from '@src/types/utils/IconAsset'; import {canApproveIOU, canIOUBePaid, canSubmitReport} from './actions/IOU'; @@ -1442,8 +1443,21 @@ function getCardSections(data: OnyxTypes.SearchResults['data']): TransactionCard * Do not use directly, use only via `getSections()` facade. */ function getWithdrawalIDSections(data: OnyxTypes.SearchResults['data']): TransactionWithdrawalIDGroupListItemType[] { - // Will be implemented as part of https://github.com/Expensify/App/pull/66078 - return data ? [] : []; + const withdrawalIDSections: Record = {}; + + for (const key in data) { + if (isGroupEntry(key)) { + const withdrawalIDGroup = data[key] as SearchWithdrawalIDGroup; + + withdrawalIDSections[key] = { + groupedBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID, + transactions: [], + ...withdrawalIDGroup, + }; + } + } + + return Object.values(withdrawalIDSections); } /** @@ -1531,7 +1545,7 @@ function getSortedSections( case CONST.SEARCH.GROUP_BY.CARD: return getSortedCardData(data as TransactionCardGroupListItemType[], localeCompare); case CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID: - return getSortedWithdrawalIDData(data as TransactionWithdrawalIDGroupListItemType[]); + return getSortedWithdrawalIDData(data as TransactionWithdrawalIDGroupListItemType[], localeCompare); } } @@ -1626,7 +1640,7 @@ function getSortedReportData(data: TransactionReportGroupListItemType[], localeC /** * @private - * Sorts report sections based on a specified column and sort order. + * Sorts member sections based on a specified column and sort order. */ function getSortedMemberData(data: TransactionMemberGroupListItemType[], localeCompare: LocaleContextProps['localeCompare']) { return data.sort((a, b) => localeCompare(a.displayName ?? a.login ?? '', b.displayName ?? b.login ?? '')); @@ -1634,7 +1648,7 @@ function getSortedMemberData(data: TransactionMemberGroupListItemType[], localeC /** * @private - * Sorts report sections based on a specified column and sort order. + * Sorts card sections based on a specified column and sort order. */ function getSortedCardData(data: TransactionCardGroupListItemType[], localeCompare: LocaleContextProps['localeCompare']) { return data.sort((a, b) => localeCompare(a.displayName ?? a.login ?? '', b.displayName ?? b.login ?? '')); @@ -1642,11 +1656,10 @@ function getSortedCardData(data: TransactionCardGroupListItemType[], localeCompa /** * @private - * Sorts report sections based on a specified column and sort order. + * Sorts withdrawal ID sections based on a specified column and sort order. */ -function getSortedWithdrawalIDData(data: TransactionWithdrawalIDGroupListItemType[]) { - // Will be implemented as part of https://github.com/Expensify/App/pull/66078 - return data ? [] : []; +function getSortedWithdrawalIDData(data: TransactionWithdrawalIDGroupListItemType[], localeCompare: LocaleContextProps['localeCompare']) { + return data.sort((a, b) => localeCompare(b.debitPosted, a.debitPosted)); } /** diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index 8535dfaf722a..d85171870cb2 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -6,6 +6,7 @@ import type TransactionListItem from '@components/SelectionList/Search/Transacti import type {ReportActionListItemType, TaskListItemType, TransactionGroupListItemType, TransactionListItemType} from '@components/SelectionList/types'; import type CONST from '@src/CONST'; import type ONYXKEYS from '@src/ONYXKEYS'; +import type {BankName} from './Bank'; import type * as OnyxCommon from './OnyxCommon'; import type {ACHAccount, ApprovalRule, ExpenseRule} from './Policy'; import type {PolicyEmployeeList} from './PolicyEmployee'; @@ -521,7 +522,7 @@ type SearchWithdrawalIDGroup = { accountNumber: string; /** Bank name */ - addressName: string; + bankName: BankName; /** When the withdrawal completed */ debitPosted: string; diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 08d44333a777..6103a82d3404 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -8,6 +8,7 @@ import type { TransactionListItemType, TransactionMemberGroupListItemType, TransactionReportGroupListItemType, + TransactionWithdrawalIDGroupListItemType, } from '@components/SelectionList/types'; import * as Expensicons from '@src/components/Icon/Expensicons'; import CONST from '@src/CONST'; @@ -41,6 +42,10 @@ const transactionID3 = '3'; const transactionID4 = '4'; const cardID = 20202020; const cardID2 = 30303030; +const entryID = 5; +const entryID2 = 6; +const accountNumber = 'XXXXXXXX6789'; +const accountNumber2 = 'XXXXXXXX5544'; const report1 = { accountID: adminAccountID, @@ -551,6 +556,46 @@ const searchResultsGroupByCard: OnyxTypes.SearchResults = { }, }; +const searchResultsGroupByWithdrawalID: OnyxTypes.SearchResults = { + data: { + personalDetailsList: {}, + [`${CONST.SEARCH.GROUP_PREFIX}${entryID}` as const]: { + entryID, + accountNumber, + bankName: CONST.BANK_NAMES.CHASE, + debitPosted: '2025-08-12 17:11:22', + count: 4, + currency: 'USD', + total: 40, + }, + [`${CONST.SEARCH.GROUP_PREFIX}${cardID2}` as const]: { + entryID: entryID2, + accountNumber: accountNumber2, + bankName: CONST.BANK_NAMES.CITIBANK, + debitPosted: '2025-08-19 18:10:54', + count: 6, + currency: 'USD', + total: 20, + }, + }, + search: { + columnsToShow: { + shouldShowCategoryColumn: false, + shouldShowTagColumn: false, + shouldShowTaxColumn: false, + }, + count: 10, + currency: 'USD', + hasMoreResults: false, + hasResults: true, + offset: 0, + status: CONST.SEARCH.STATUS.EXPENSE.ALL, + total: 60, + isLoading: false, + type: 'expense', + }, +}; + const reportActionListItems = [ { accountID: 18439984, @@ -1257,6 +1302,56 @@ const transactionCardGroupListItemsSorted: TransactionCardGroupListItemType[] = }, ]; +const transactionWithdrawalIDGroupListItems: TransactionWithdrawalIDGroupListItemType[] = [ + { + bankName: CONST.BANK_NAMES.CHASE, + entryID, + accountNumber, + debitPosted: '2025-08-12 17:11:22', + count: 4, + currency: 'USD', + total: 40, + groupedBy: 'withdrawal-id', + transactions: [], + }, + { + bankName: CONST.BANK_NAMES.CITIBANK, + entryID: entryID2, + accountNumber: accountNumber2, + debitPosted: '2025-08-19 18:10:54', + count: 6, + currency: 'USD', + total: 20, + groupedBy: 'withdrawal-id', + transactions: [], + }, +]; + +const transactionWithdrawalIDGroupListItemsSorted: TransactionWithdrawalIDGroupListItemType[] = [ + { + bankName: CONST.BANK_NAMES.CITIBANK, + entryID: entryID2, + accountNumber: accountNumber2, + debitPosted: '2025-08-19 18:10:54', + count: 6, + currency: 'USD', + total: 20, + groupedBy: 'withdrawal-id', + transactions: [], + }, + { + bankName: CONST.BANK_NAMES.CHASE, + entryID, + accountNumber, + debitPosted: '2025-08-12 17:11:22', + count: 4, + currency: 'USD', + total: 40, + groupedBy: 'withdrawal-id', + transactions: [], + }, +]; + describe('SearchUIUtils', () => { beforeAll(async () => { Onyx.init({ @@ -1577,6 +1672,19 @@ describe('SearchUIUtils', () => { ), ).toStrictEqual(transactionCardGroupListItems); }); + + it('should return getWithdrawalIDSections result when type is EXPENSE and groupBy is withdrawal-id', () => { + expect( + SearchUIUtils.getSections( + CONST.SEARCH.DATA_TYPES.EXPENSE, + searchResultsGroupByWithdrawalID.data, + searchResultsGroupByWithdrawalID.search, + 2074551, + formatPhoneNumber, + CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID, + ), + ).toStrictEqual(transactionWithdrawalIDGroupListItems); + }); }); describe('Test getSortedSections', () => { @@ -1648,6 +1756,20 @@ describe('SearchUIUtils', () => { SearchUIUtils.getSortedSections(CONST.SEARCH.DATA_TYPES.EXPENSE, '', transactionCardGroupListItems, localeCompare, 'date', 'asc', CONST.SEARCH.GROUP_BY.CARD), ).toStrictEqual(transactionCardGroupListItemsSorted); }); + + it('should return getSortedWithdrawalIDData result when type is EXPENSE and groupBy is withdrawal-id', () => { + expect( + SearchUIUtils.getSortedSections( + CONST.SEARCH.DATA_TYPES.EXPENSE, + '', + transactionWithdrawalIDGroupListItems, + localeCompare, + 'date', + 'asc', + CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID, + ), + ).toStrictEqual(transactionWithdrawalIDGroupListItemsSorted); + }); }); describe('Test createTypeMenuItems', () => {