diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 4625e37e8507..59f3828eb304 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -7053,6 +7053,8 @@ const CONST = { BANK_ACCOUNT: this.TABLE_COLUMNS.GROUP_BANK_ACCOUNT, WITHDRAWAL_ID: this.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID, EXPENSES: this.TABLE_COLUMNS.GROUP_EXPENSES, + AMOUNT_DEBITED: this.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + AMOUNT_REIMBURSED: this.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, TOTAL: this.TABLE_COLUMNS.GROUP_TOTAL, }, CATEGORY: { @@ -7131,6 +7133,8 @@ const CONST = { this.TABLE_COLUMNS.GROUP_BANK_ACCOUNT, this.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID, this.TABLE_COLUMNS.GROUP_EXPENSES, + this.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + this.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, this.TABLE_COLUMNS.GROUP_TOTAL, ], CATEGORY: [this.TABLE_COLUMNS.GROUP_CATEGORY, this.TABLE_COLUMNS.GROUP_EXPENSES, this.TABLE_COLUMNS.GROUP_TOTAL], @@ -7251,6 +7255,8 @@ const CONST = { GROUP_YEAR: 'groupyear', GROUP_QUARTER: 'groupquarter', GROUP_WITHDRAWAL_STATUS: 'groupWithdrawalStatus', + GROUP_AMOUNT_DEBITED: 'groupAmountDebited', + GROUP_AMOUNT_REIMBURSED: 'groupAmountReimbursed', }, SYNTAX_OPERATORS: { AND: 'and', @@ -7470,6 +7476,8 @@ const CONST = { [this.TABLE_COLUMNS.GROUP_YEAR]: 'group-year', [this.TABLE_COLUMNS.GROUP_QUARTER]: 'group-quarter', [this.TABLE_COLUMNS.GROUP_WITHDRAWAL_STATUS]: 'group-withdrawal-status', + [this.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: 'group-amount-debited', + [this.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: 'group-amount-reimbursed', }; }, NOT_PREFIX: '-', diff --git a/src/components/Search/FilterDropdowns/SortByPopup.tsx b/src/components/Search/FilterDropdowns/SortByPopup.tsx index 4fd70677e466..ab5d17990869 100644 --- a/src/components/Search/FilterDropdowns/SortByPopup.tsx +++ b/src/components/Search/FilterDropdowns/SortByPopup.tsx @@ -55,7 +55,7 @@ function SortByPopup({searchResults, queryJSON, groupBy, onSort, onSortOrderPres const searchDataType = shouldUseLiveData ? CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT : searchResults?.search?.type; const currentColumns = !searchResults?.data ? [] - : getColumnsToShow({currentAccountID: accountID, data: searchResults.data, visibleColumns, type: searchDataType, groupBy: groupBy?.value}); + : getColumnsToShow({currentAccountID: accountID, data: searchResults.data, visibleColumns, type: searchDataType, groupBy: groupBy?.value, sortBy: queryJSON.sortBy}); const sortableColumns = getSortByOptions(currentColumns, translate); const sortOrder = queryJSON.sortOrder; diff --git a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx index 7327f9aa8b29..67f72a025cdc 100644 --- a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx +++ b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx @@ -93,6 +93,8 @@ function WithdrawalIDListItemHeaderImpl({ withdrawalIDItem.debitPosted, DateUtils.doesDateBelongToAPastYear(withdrawalIDItem.debitPosted) ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, ); + const {debitedAmount, debitedCurrency, creditedAmount, creditedCurrency} = withdrawalIDItem; + const badgeProps = getSettlementStatusBadgeProps(withdrawalIDItem.state, translate, theme); const settlementStatus = getSettlementStatus(withdrawalIDItem.state); const statusBadge = !!badgeProps && ( @@ -177,6 +179,33 @@ function WithdrawalIDListItemHeaderImpl({ ), + // A settlement that did not convert currencies reports neither amount, and an amount says nothing without the currency it moved in. + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: ( + + {!!debitedAmount && !!debitedCurrency && ( + + )} + + ), + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: ( + + {!!creditedAmount && !!creditedCurrency && ( + + )} + + ), [CONST.SEARCH.TABLE_COLUMNS.GROUP_TOTAL]: ( { - const commonGroupHeaders: SearchColumnConfig[] = [ - { - columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_EXPENSES, - translationKey: 'common.expenses' as TranslationPaths, - isColumnSortable: true, - }, - { - columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_TOTAL, - translationKey: 'common.total' as TranslationPaths, - isColumnSortable: true, - }, - ]; + const groupExpensesHeader: SearchColumnConfig = { + columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_EXPENSES, + translationKey: 'common.expenses' as TranslationPaths, + isColumnSortable: true, + }; + const groupTotalHeader: SearchColumnConfig = { + columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_TOTAL, + translationKey: 'common.total' as TranslationPaths, + isColumnSortable: true, + }; + const commonGroupHeaders: SearchColumnConfig[] = [groupExpensesHeader, groupTotalHeader]; switch (groupBy) { case CONST.SEARCH.GROUP_BY.FROM: return [ @@ -405,7 +404,18 @@ const getTransactionGroupHeaders = (groupBy: SearchGroupBy, icons: SearchHeaderI columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID, translationKey: 'common.withdrawalID', }, - ...commonGroupHeaders, + groupExpensesHeader, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + translationKey: 'common.amountDebited', + isColumnSortable: true, + }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, + translationKey: 'common.amountReimbursed', + isColumnSortable: true, + }, + groupTotalHeader, ]; case CONST.SEARCH.GROUP_BY.CATEGORY: return [ diff --git a/src/components/Search/SortableTableHeader.tsx b/src/components/Search/SortableTableHeader.tsx index c535480b6d44..861b4b84abea 100644 --- a/src/components/Search/SortableTableHeader.tsx +++ b/src/components/Search/SortableTableHeader.tsx @@ -80,9 +80,10 @@ function SortableTableHeader({ const sortByColumnName = sortColumnName ?? columnName; const isActive = sortBy === sortByColumnName; const isReimbursableOrBillableColumn = columnName === CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE || columnName === CONST.SEARCH.TABLE_COLUMNS.BILLABLE; + const isConversionAmountColumn = columnName === CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED || columnName === CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED; const textStyle = [ columnName === CONST.SEARCH.TABLE_COLUMNS.RECEIPT ? StyleUtils.getTextOverflowStyle('clip') : null, - isReimbursableOrBillableColumn ? styles.flexShrink1 : null, + isReimbursableOrBillableColumn || isConversionAmountColumn ? styles.flexShrink1 : null, ]; return ( diff --git a/src/components/Search/hooks/useSearchSnapshot.ts b/src/components/Search/hooks/useSearchSnapshot.ts index a6a8e82fa8ea..87db5d0a4b9d 100644 --- a/src/components/Search/hooks/useSearchSnapshot.ts +++ b/src/components/Search/hooks/useSearchSnapshot.ts @@ -377,6 +377,7 @@ function useSearchSnapshot({queryJSON, searchResults, newSearchResultKeys, trans groupBy: validGroupBy, shouldUseStrictDefaultExpenseColumns: currentSearchKey === CONST.SEARCH.SEARCH_KEYS.EXPENSES && isDefaultExpensesQuery(queryJSON), fallbackPolicyID: policyForMovingExpensesID, + sortBy: queryJSON.sortBy, }); })(); diff --git a/src/hooks/useSearchOverlay.tsx b/src/hooks/useSearchOverlay.tsx index 431b120011c8..e4d1a1cd387c 100644 --- a/src/hooks/useSearchOverlay.tsx +++ b/src/hooks/useSearchOverlay.tsx @@ -122,6 +122,7 @@ function useSearchOverlay({ groupBy: validGroupBy, shouldUseStrictDefaultExpenseColumns, fallbackPolicyID: policyForMovingExpensesID, + sortBy: queryJSON.sortBy, }); })(); diff --git a/src/languages/de.ts b/src/languages/de.ts index 0a4cbfda34f4..3d95b679832b 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -405,6 +405,8 @@ const translations: TranslationDeepObject = { longReportID: 'Langer Bericht-ID', withdrawalID: 'Auszahlungs-ID', internationalReimbursementIDs: 'Internationale Erstattungs-IDs', + amountDebited: 'Belasteter Betrag', + amountReimbursed: 'Erstatteter Betrag', withdrawalStatus: 'Auszahlungsstatus', paidStatus: 'Status: Bezahlt', bankAccounts: 'Bankkonten', diff --git a/src/languages/en.ts b/src/languages/en.ts index 40383d04d1ba..3b25abcfef66 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -434,6 +434,8 @@ const translations = { longReportID: 'Long Report ID', withdrawalID: 'Withdrawal ID', internationalReimbursementIDs: 'International reimbursement IDs', + amountDebited: 'Amount debited', + amountReimbursed: 'Amount reimbursed', withdrawalStatus: 'Withdrawal status', paidStatus: 'Paid status', bankAccounts: 'Bank accounts', diff --git a/src/languages/es.ts b/src/languages/es.ts index 40b0f1fec1f8..b9a0f77069a5 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -463,6 +463,8 @@ const translations: TranslationDeepObject = { reimbursableTotal: 'Total reembolsable', nonReimbursableTotal: 'Total no reembolsable', internationalReimbursementIDs: 'IDs de reembolso internacional', + amountDebited: 'Importe debitado', + amountReimbursed: 'Importe reembolsado', opensInNewTab: 'Se abre en una nueva pestaña', locked: 'Bloqueado', month: 'Monat', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 76b9f7051b99..b4cfbce1a773 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: 'ID de note de frais longue', withdrawalID: 'ID de retrait', internationalReimbursementIDs: 'ID de remboursement international', + amountDebited: 'Montant débité', + amountReimbursed: 'Montant remboursé', withdrawalStatus: 'Statut de retrait', paidStatus: 'Statut payé', bankAccounts: 'Comptes bancaires', diff --git a/src/languages/it.ts b/src/languages/it.ts index 52954061ba89..a6f7886ea5dd 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -405,6 +405,8 @@ const translations: TranslationDeepObject = { longReportID: 'ID report dettagliato', withdrawalID: 'ID prelievo', internationalReimbursementIDs: 'ID di rimborso internazionale', + amountDebited: 'Importo addebitato', + amountReimbursed: 'Importo rimborsato', withdrawalStatus: 'Stato del prelievo', paidStatus: 'Stato di pagamento', bankAccounts: 'Conti bancari', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index ddae1697c831..06ba080157cc 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: '長いレポートID', withdrawalID: '出金ID', internationalReimbursementIDs: '国際払い戻しID', + amountDebited: '引き落とし金額', + amountReimbursed: '払い戻し金額', withdrawalStatus: '出金ステータス', paidStatus: '支払済みステータス', bankAccounts: '銀行口座', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index fc88dd4b2d0c..4088620ce56c 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: 'Lang rapport-ID', withdrawalID: 'Opname-ID', internationalReimbursementIDs: 'Internationale terugbetalings-ID’s', + amountDebited: 'Afgeschreven bedrag', + amountReimbursed: 'Terugbetaald bedrag', withdrawalStatus: 'Opnamestatus', paidStatus: 'Betaald-status', bankAccounts: 'Bankrekeningen', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index f891c05a51ca..7b230204d037 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: 'Długi identyfikator raportu', withdrawalID: 'Identyfikator wypłaty', internationalReimbursementIDs: 'Identyfikatory zwrotów międzynarodowych', + amountDebited: 'Kwota obciążenia', + amountReimbursed: 'Kwota zwrotu', withdrawalStatus: 'Status wypłaty', paidStatus: 'Status: opłacono', bankAccounts: 'Konta bankowe', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 62d2ae04a800..01609d40dc4a 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: 'ID de relatório longo', withdrawalID: 'ID do saque', internationalReimbursementIDs: 'IDs de reembolso internacional', + amountDebited: 'Valor debitado', + amountReimbursed: 'Valor reembolsado', withdrawalStatus: 'Status do saque', paidStatus: 'Status pago', bankAccounts: 'Contas bancárias', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 82a573880a76..4b6ec6f9ddbd 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -404,6 +404,8 @@ const translations: TranslationDeepObject = { longReportID: '长报表 ID', withdrawalID: '提现编号', internationalReimbursementIDs: '国际报销 ID', + amountDebited: '扣款金额', + amountReimbursed: '报销金额', withdrawalStatus: '提现状态', paidStatus: '已付款状态', bankAccounts: '银行账户', diff --git a/src/libs/SearchParser/autocompleteParser.js b/src/libs/SearchParser/autocompleteParser.js index 3f3d7a740d60..dc445c90f584 100644 --- a/src/libs/SearchParser/autocompleteParser.js +++ b/src/libs/SearchParser/autocompleteParser.js @@ -276,21 +276,23 @@ function peg$parse(input, options) { var peg$c90 = "group-bank-account"; var peg$c91 = "group-withdrawn"; var peg$c92 = "group-withdrawal-id"; - var peg$c93 = "group-category"; - var peg$c94 = "group-tag"; - var peg$c95 = "group-merchant"; - var peg$c96 = "group-month"; - var peg$c97 = "group-week"; - var peg$c98 = "group-year"; - var peg$c99 = "group-quarter"; - var peg$c100 = "!="; - var peg$c101 = ">="; - var peg$c102 = ">"; - var peg$c103 = "<="; - var peg$c104 = "<"; - var peg$c105 = "\u201C"; - var peg$c106 = "\u201D"; - var peg$c107 = "\""; + var peg$c93 = "group-amount-debited"; + var peg$c94 = "group-amount-reimbursed"; + var peg$c95 = "group-category"; + var peg$c96 = "group-tag"; + var peg$c97 = "group-merchant"; + var peg$c98 = "group-month"; + var peg$c99 = "group-week"; + var peg$c100 = "group-year"; + var peg$c101 = "group-quarter"; + var peg$c102 = "!="; + var peg$c103 = ">="; + var peg$c104 = ">"; + var peg$c105 = "<="; + var peg$c106 = "<"; + var peg$c107 = "\u201C"; + var peg$c108 = "\u201D"; + var peg$c109 = "\""; var peg$r0 = /^[ \t\r\n\xA0,:=<>!]/; var peg$r1 = /^[:=]/; @@ -403,36 +405,38 @@ function peg$parse(input, options) { var peg$e94 = peg$literalExpectation("group-bank-account", true); var peg$e95 = peg$literalExpectation("group-withdrawn", true); var peg$e96 = peg$literalExpectation("group-withdrawal-id", true); - var peg$e97 = peg$literalExpectation("group-category", true); - var peg$e98 = peg$literalExpectation("group-tag", true); - var peg$e99 = peg$literalExpectation("group-merchant", true); - var peg$e100 = peg$literalExpectation("group-month", true); - var peg$e101 = peg$literalExpectation("group-week", true); - var peg$e102 = peg$literalExpectation("group-year", true); - var peg$e103 = peg$literalExpectation("group-quarter", true); - var peg$e104 = peg$otherExpectation("operator"); - var peg$e105 = peg$literalExpectation("!=", false); - var peg$e106 = peg$literalExpectation(">=", false); - var peg$e107 = peg$literalExpectation(">", false); - var peg$e108 = peg$literalExpectation("<=", false); - var peg$e109 = peg$literalExpectation("<", false); - var peg$e110 = peg$otherExpectation("word"); - var peg$e111 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false); - var peg$e112 = peg$otherExpectation("whitespace"); - var peg$e113 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false); - var peg$e114 = peg$otherExpectation("quote"); - var peg$e115 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false); - var peg$e116 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false); - var peg$e117 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false); - var peg$e118 = peg$literalExpectation("\u201C", false); - var peg$e119 = peg$literalExpectation("\u201D", false); - var peg$e120 = peg$literalExpectation("\"", false); - var peg$e121 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false); - var peg$e122 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); - var peg$e123 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false); - var peg$e124 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false); - var peg$e125 = peg$classExpectation([","], false, false); - var peg$e126 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ","], false, false); + var peg$e97 = peg$literalExpectation("group-amount-debited", true); + var peg$e98 = peg$literalExpectation("group-amount-reimbursed", true); + var peg$e99 = peg$literalExpectation("group-category", true); + var peg$e100 = peg$literalExpectation("group-tag", true); + var peg$e101 = peg$literalExpectation("group-merchant", true); + var peg$e102 = peg$literalExpectation("group-month", true); + var peg$e103 = peg$literalExpectation("group-week", true); + var peg$e104 = peg$literalExpectation("group-year", true); + var peg$e105 = peg$literalExpectation("group-quarter", true); + var peg$e106 = peg$otherExpectation("operator"); + var peg$e107 = peg$literalExpectation("!=", false); + var peg$e108 = peg$literalExpectation(">=", false); + var peg$e109 = peg$literalExpectation(">", false); + var peg$e110 = peg$literalExpectation("<=", false); + var peg$e111 = peg$literalExpectation("<", false); + var peg$e112 = peg$otherExpectation("word"); + var peg$e113 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false); + var peg$e114 = peg$otherExpectation("whitespace"); + var peg$e115 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false); + var peg$e116 = peg$otherExpectation("quote"); + var peg$e117 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false); + var peg$e118 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false); + var peg$e119 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false); + var peg$e120 = peg$literalExpectation("\u201C", false); + var peg$e121 = peg$literalExpectation("\u201D", false); + var peg$e122 = peg$literalExpectation("\"", false); + var peg$e123 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e124 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e125 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false); + var peg$e126 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false); + var peg$e127 = peg$classExpectation([","], false, false); + var peg$e128 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ","], false, false); var peg$f0 = function(ranges) { return { autocomplete, ranges }; }; var peg$f1 = function(filters) { return filters.filter(Boolean).flat(); }; @@ -576,39 +580,41 @@ function peg$parse(input, options) { var peg$f81 = function() { return "groupBankAccount"; }; var peg$f82 = function() { return "groupWithdrawn"; }; var peg$f83 = function() { return "groupWithdrawalID"; }; - var peg$f84 = function() { return "groupCategory"; }; - var peg$f85 = function() { return "groupTag"; }; - var peg$f86 = function() { return "groupMerchant"; }; - var peg$f87 = function() { return "groupmonth"; }; - var peg$f88 = function() { return "groupweek"; }; - var peg$f89 = function() { return "groupyear"; }; - var peg$f90 = function() { return "groupquarter"; }; - var peg$f91 = function() { return "eq"; }; - var peg$f92 = function() { return "neq"; }; - var peg$f93 = function() { return "gte"; }; - var peg$f94 = function() { return "gt"; }; - var peg$f95 = function() { return "lte"; }; - var peg$f96 = function() { return "lt"; }; - var peg$f97 = function(o) { + var peg$f84 = function() { return "groupAmountDebited"; }; + var peg$f85 = function() { return "groupAmountReimbursed"; }; + var peg$f86 = function() { return "groupCategory"; }; + var peg$f87 = function() { return "groupTag"; }; + var peg$f88 = function() { return "groupMerchant"; }; + var peg$f89 = function() { return "groupmonth"; }; + var peg$f90 = function() { return "groupweek"; }; + var peg$f91 = function() { return "groupyear"; }; + var peg$f92 = function() { return "groupquarter"; }; + var peg$f93 = function() { return "eq"; }; + var peg$f94 = function() { return "neq"; }; + var peg$f95 = function() { return "gte"; }; + var peg$f96 = function() { return "gt"; }; + var peg$f97 = function() { return "lte"; }; + var peg$f98 = function() { return "lt"; }; + var peg$f99 = function(o) { if (nameOperator) { expectingNestedQuote = (o === "eq"); // Use simple parser if no valid operator is found } isColumnsContext = false; return o; }; - var peg$f98 = function(chars) { return chars.join("").trim(); }; - var peg$f99 = function() { + var peg$f100 = function(chars) { return chars.join("").trim(); }; + var peg$f101 = function() { isColumnsContext = false; return "and"; }; - var peg$f100 = function() { return expectingNestedQuote; }; - var peg$f101 = function(start, inner, end) { //handle no-breaking space + var peg$f102 = function() { return expectingNestedQuote; }; + var peg$f103 = function(start, inner, end) { //handle no-breaking space return [...start, '"', ...inner, '"', ...end].join(""); }; - var peg$f102 = function(start) {return "“"}; - var peg$f103 = function(start) {return "”"}; - var peg$f104 = function(start) {return "\""}; - var peg$f105 = function(start, inner, end) { + var peg$f104 = function(start) {return "“"}; + var peg$f105 = function(start) {return "”"}; + var peg$f106 = function(start) {return "\""}; + var peg$f107 = function(start, inner, end) { return [...start, '"', ...inner, '"'].join(""); }; var peg$currPos = options.peg$currPos | 0; @@ -2542,19 +2548,25 @@ function peg$parse(input, options) { if (s0 === peg$FAILED) { s0 = peg$parsegroupWithdrawalId(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupCategory(); + s0 = peg$parsegroupAmountDebited(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupTag(); + s0 = peg$parsegroupAmountReimbursed(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupMerchant(); + s0 = peg$parsegroupCategory(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupMonth(); + s0 = peg$parsegroupTag(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupWeek(); + s0 = peg$parsegroupMerchant(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupYear(); + s0 = peg$parsegroupMonth(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupQuarter(); + s0 = peg$parsegroupWeek(); + if (s0 === peg$FAILED) { + s0 = peg$parsegroupYear(); + if (s0 === peg$FAILED) { + s0 = peg$parsegroupQuarter(); + } + } } } } @@ -3503,13 +3515,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupCategory() { + function peg$parsegroupAmountDebited() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 14); + s1 = input.substr(peg$currPos, 20); if (s1.toLowerCase() === peg$c93) { - peg$currPos += 14; + peg$currPos += 20; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e97); } @@ -3540,13 +3552,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupTag() { + function peg$parsegroupAmountReimbursed() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 9); + s1 = input.substr(peg$currPos, 23); if (s1.toLowerCase() === peg$c94) { - peg$currPos += 9; + peg$currPos += 23; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e98); } @@ -3577,7 +3589,7 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupMerchant() { + function peg$parsegroupCategory() { var s0, s1, s2, s3; s0 = peg$currPos; @@ -3614,13 +3626,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupMonth() { + function peg$parsegroupTag() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 11); + s1 = input.substr(peg$currPos, 9); if (s1.toLowerCase() === peg$c96) { - peg$currPos += 11; + peg$currPos += 9; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e100); } @@ -3651,13 +3663,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupWeek() { + function peg$parsegroupMerchant() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 10); + s1 = input.substr(peg$currPos, 14); if (s1.toLowerCase() === peg$c97) { - peg$currPos += 10; + peg$currPos += 14; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e101); } @@ -3688,13 +3700,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupYear() { + function peg$parsegroupMonth() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 10); + s1 = input.substr(peg$currPos, 11); if (s1.toLowerCase() === peg$c98) { - peg$currPos += 10; + peg$currPos += 11; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e102); } @@ -3725,13 +3737,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupQuarter() { + function peg$parsegroupWeek() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 13); + s1 = input.substr(peg$currPos, 10); if (s1.toLowerCase() === peg$c99) { - peg$currPos += 13; + peg$currPos += 10; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e103); } @@ -3762,6 +3774,80 @@ function peg$parse(input, options) { return s0; } + function peg$parsegroupYear() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = input.substr(peg$currPos, 10); + if (s1.toLowerCase() === peg$c100) { + peg$currPos += 10; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e104); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parsewordBoundary(); + peg$silentFails--; + if (s3 !== peg$FAILED) { + peg$currPos = s2; + s2 = undefined; + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f91(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsegroupQuarter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = input.substr(peg$currPos, 13); + if (s1.toLowerCase() === peg$c101) { + peg$currPos += 13; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e105); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parsewordBoundary(); + peg$silentFails--; + if (s3 !== peg$FAILED) { + peg$currPos = s2; + s2 = undefined; + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f92(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + function peg$parseoperator() { var s0, s1; @@ -3776,77 +3862,77 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f91(); + s1 = peg$f93(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c100) { - s1 = peg$c100; + if (input.substr(peg$currPos, 2) === peg$c102) { + s1 = peg$c102; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e105); } + if (peg$silentFails === 0) { peg$fail(peg$e107); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f92(); + s1 = peg$f94(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c101) { - s1 = peg$c101; + if (input.substr(peg$currPos, 2) === peg$c103) { + s1 = peg$c103; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e106); } + if (peg$silentFails === 0) { peg$fail(peg$e108); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f93(); + s1 = peg$f95(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 62) { - s1 = peg$c102; + s1 = peg$c104; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e107); } + if (peg$silentFails === 0) { peg$fail(peg$e109); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f94(); + s1 = peg$f96(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c103) { - s1 = peg$c103; + if (input.substr(peg$currPos, 2) === peg$c105) { + s1 = peg$c105; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e108); } + if (peg$silentFails === 0) { peg$fail(peg$e110); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f95(); + s1 = peg$f97(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c104; + s1 = peg$c106; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e109); } + if (peg$silentFails === 0) { peg$fail(peg$e111); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f96(); + s1 = peg$f98(); } s0 = s1; } @@ -3857,7 +3943,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e104); } + if (peg$silentFails === 0) { peg$fail(peg$e106); } } return s0; @@ -3870,7 +3956,7 @@ function peg$parse(input, options) { s1 = peg$parseoperator(); if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f97(s1); + s1 = peg$f99(s1); } s0 = s1; @@ -3888,7 +3974,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e111); } + if (peg$silentFails === 0) { peg$fail(peg$e113); } } if (s2 !== peg$FAILED) { while (s2 !== peg$FAILED) { @@ -3898,7 +3984,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e111); } + if (peg$silentFails === 0) { peg$fail(peg$e113); } } } } else { @@ -3906,13 +3992,13 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f98(s1); + s1 = peg$f100(s1); } s0 = s1; peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e110); } + if (peg$silentFails === 0) { peg$fail(peg$e112); } } return s0; @@ -3924,7 +4010,7 @@ function peg$parse(input, options) { s0 = peg$currPos; s1 = peg$parse_(); peg$savedPos = s0; - s1 = peg$f99(); + s1 = peg$f101(); s0 = s1; return s0; @@ -3940,7 +4026,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } while (s1 !== peg$FAILED) { s0.push(s1); @@ -3949,12 +4035,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } } peg$silentFails--; s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e112); } + if (peg$silentFails === 0) { peg$fail(peg$e114); } return s0; } @@ -3964,7 +4050,7 @@ function peg$parse(input, options) { s0 = peg$currPos; peg$savedPos = peg$currPos; - s1 = peg$f100(); + s1 = peg$f102(); if (s1) { s1 = undefined; } else { @@ -4001,7 +4087,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4010,7 +4096,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } } s2 = input.charAt(peg$currPos); @@ -4018,7 +4104,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } if (s2 !== peg$FAILED) { s3 = []; @@ -4027,7 +4113,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -4036,7 +4122,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } } s4 = input.charAt(peg$currPos); @@ -4044,7 +4130,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } if (s4 !== peg$FAILED) { s5 = []; @@ -4053,7 +4139,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e111); } + if (peg$silentFails === 0) { peg$fail(peg$e113); } } while (s6 !== peg$FAILED) { s5.push(s6); @@ -4062,11 +4148,11 @@ function peg$parse(input, options) { peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e111); } + if (peg$silentFails === 0) { peg$fail(peg$e113); } } } peg$savedPos = s0; - s0 = peg$f101(s1, s3, s5); + s0 = peg$f103(s1, s3, s5); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -4078,7 +4164,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e114); } + if (peg$silentFails === 0) { peg$fail(peg$e116); } } return s0; @@ -4095,7 +4181,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4104,7 +4190,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } } s2 = input.charAt(peg$currPos); @@ -4112,7 +4198,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } if (s2 !== peg$FAILED) { s3 = []; @@ -4121,7 +4207,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } if (s4 === peg$FAILED) { s4 = peg$currPos; @@ -4137,15 +4223,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8220) { - s6 = peg$c105; + s6 = peg$c107; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f102(s1); + s4 = peg$f104(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4168,15 +4254,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8221) { - s6 = peg$c106; + s6 = peg$c108; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f103(s1); + s4 = peg$f105(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4199,15 +4285,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s6 = peg$c107; + s6 = peg$c109; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e120); } + if (peg$silentFails === 0) { peg$fail(peg$e122); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f104(s1); + s4 = peg$f106(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4226,7 +4312,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } if (s4 === peg$FAILED) { s4 = peg$currPos; @@ -4242,15 +4328,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8220) { - s6 = peg$c105; + s6 = peg$c107; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f102(s1); + s4 = peg$f104(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4273,15 +4359,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8221) { - s6 = peg$c106; + s6 = peg$c108; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f103(s1); + s4 = peg$f105(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4304,15 +4390,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s6 = peg$c107; + s6 = peg$c109; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e120); } + if (peg$silentFails === 0) { peg$fail(peg$e122); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f104(s1); + s4 = peg$f106(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4328,7 +4414,7 @@ function peg$parse(input, options) { s4 = peg$parseclosingQuote(); if (s4 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f105(s1, s3, s4); + s0 = peg$f107(s1, s3, s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -4340,7 +4426,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e114); } + if (peg$silentFails === 0) { peg$fail(peg$e116); } } return s0; @@ -4355,7 +4441,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -4393,7 +4479,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e121); } + if (peg$silentFails === 0) { peg$fail(peg$e123); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4402,7 +4488,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e121); } + if (peg$silentFails === 0) { peg$fail(peg$e123); } } } s2 = []; @@ -4411,7 +4497,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e122); } + if (peg$silentFails === 0) { peg$fail(peg$e124); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -4420,7 +4506,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e122); } + if (peg$silentFails === 0) { peg$fail(peg$e124); } } } s3 = []; @@ -4429,7 +4515,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e123); } + if (peg$silentFails === 0) { peg$fail(peg$e125); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -4438,7 +4524,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e123); } + if (peg$silentFails === 0) { peg$fail(peg$e125); } } } s4 = peg$parseoperator(); @@ -4457,7 +4543,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e124); } + if (peg$silentFails === 0) { peg$fail(peg$e126); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4466,7 +4552,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e124); } + if (peg$silentFails === 0) { peg$fail(peg$e126); } } } s2 = peg$currPos; @@ -4513,7 +4599,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e125); } + if (peg$silentFails === 0) { peg$fail(peg$e127); } } } } @@ -4529,7 +4615,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e126); } + if (peg$silentFails === 0) { peg$fail(peg$e128); } } if (s0 === peg$FAILED) { s0 = peg$currPos; diff --git a/src/libs/SearchParser/baseRules.peggy b/src/libs/SearchParser/baseRules.peggy index a6afcc350bfa..501e62d9352c 100644 --- a/src/libs/SearchParser/baseRules.peggy +++ b/src/libs/SearchParser/baseRules.peggy @@ -125,6 +125,8 @@ columnsValues / groupBankAccount / groupWithdrawn / groupWithdrawalId + / groupAmountDebited + / groupAmountReimbursed / groupCategory / groupTag / groupMerchant @@ -159,6 +161,8 @@ groupFeed = "group-feed"i &wordBoundary { return "gr groupBankAccount = "group-bank-account"i &wordBoundary { return "groupBankAccount"; } groupWithdrawn = "group-withdrawn"i &wordBoundary { return "groupWithdrawn"; } groupWithdrawalId = "group-withdrawal-id"i &wordBoundary { return "groupWithdrawalID"; } +groupAmountDebited = "group-amount-debited"i &wordBoundary { return "groupAmountDebited"; } +groupAmountReimbursed = "group-amount-reimbursed"i &wordBoundary { return "groupAmountReimbursed"; } groupCategory = "group-category"i &wordBoundary { return "groupCategory"; } groupTag = "group-tag"i &wordBoundary { return "groupTag"; } groupMerchant = "group-merchant"i &wordBoundary { return "groupMerchant"; } diff --git a/src/libs/SearchParser/searchParser.js b/src/libs/SearchParser/searchParser.js index 23ce77c8a6ee..9be7e4142a22 100644 --- a/src/libs/SearchParser/searchParser.js +++ b/src/libs/SearchParser/searchParser.js @@ -277,21 +277,23 @@ function peg$parse(input, options) { var peg$c90 = "group-bank-account"; var peg$c91 = "group-withdrawn"; var peg$c92 = "group-withdrawal-id"; - var peg$c93 = "group-category"; - var peg$c94 = "group-tag"; - var peg$c95 = "group-merchant"; - var peg$c96 = "group-month"; - var peg$c97 = "group-week"; - var peg$c98 = "group-year"; - var peg$c99 = "group-quarter"; - var peg$c100 = "!="; - var peg$c101 = ">="; - var peg$c102 = ">"; - var peg$c103 = "<="; - var peg$c104 = "<"; - var peg$c105 = "\u201C"; - var peg$c106 = "\u201D"; - var peg$c107 = "\""; + var peg$c93 = "group-amount-debited"; + var peg$c94 = "group-amount-reimbursed"; + var peg$c95 = "group-category"; + var peg$c96 = "group-tag"; + var peg$c97 = "group-merchant"; + var peg$c98 = "group-month"; + var peg$c99 = "group-week"; + var peg$c100 = "group-year"; + var peg$c101 = "group-quarter"; + var peg$c102 = "!="; + var peg$c103 = ">="; + var peg$c104 = ">"; + var peg$c105 = "<="; + var peg$c106 = "<"; + var peg$c107 = "\u201C"; + var peg$c108 = "\u201D"; + var peg$c109 = "\""; var peg$r0 = /^[^ \t\r\n\xA0]/; var peg$r1 = /^[ \t\r\n\xA0,:=<>!]/; @@ -407,36 +409,38 @@ function peg$parse(input, options) { var peg$e96 = peg$literalExpectation("group-bank-account", true); var peg$e97 = peg$literalExpectation("group-withdrawn", true); var peg$e98 = peg$literalExpectation("group-withdrawal-id", true); - var peg$e99 = peg$literalExpectation("group-category", true); - var peg$e100 = peg$literalExpectation("group-tag", true); - var peg$e101 = peg$literalExpectation("group-merchant", true); - var peg$e102 = peg$literalExpectation("group-month", true); - var peg$e103 = peg$literalExpectation("group-week", true); - var peg$e104 = peg$literalExpectation("group-year", true); - var peg$e105 = peg$literalExpectation("group-quarter", true); - var peg$e106 = peg$otherExpectation("operator"); - var peg$e107 = peg$literalExpectation("!=", false); - var peg$e108 = peg$literalExpectation(">=", false); - var peg$e109 = peg$literalExpectation(">", false); - var peg$e110 = peg$literalExpectation("<=", false); - var peg$e111 = peg$literalExpectation("<", false); - var peg$e112 = peg$otherExpectation("word"); - var peg$e113 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false); - var peg$e114 = peg$otherExpectation("whitespace"); - var peg$e115 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false); - var peg$e116 = peg$otherExpectation("quote"); - var peg$e117 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false); - var peg$e118 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false); - var peg$e119 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false); - var peg$e120 = peg$literalExpectation("\u201C", false); - var peg$e121 = peg$literalExpectation("\u201D", false); - var peg$e122 = peg$literalExpectation("\"", false); - var peg$e123 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false); - var peg$e124 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); - var peg$e125 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false); - var peg$e126 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false); - var peg$e127 = peg$classExpectation([","], false, false); - var peg$e128 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ","], false, false); + var peg$e99 = peg$literalExpectation("group-amount-debited", true); + var peg$e100 = peg$literalExpectation("group-amount-reimbursed", true); + var peg$e101 = peg$literalExpectation("group-category", true); + var peg$e102 = peg$literalExpectation("group-tag", true); + var peg$e103 = peg$literalExpectation("group-merchant", true); + var peg$e104 = peg$literalExpectation("group-month", true); + var peg$e105 = peg$literalExpectation("group-week", true); + var peg$e106 = peg$literalExpectation("group-year", true); + var peg$e107 = peg$literalExpectation("group-quarter", true); + var peg$e108 = peg$otherExpectation("operator"); + var peg$e109 = peg$literalExpectation("!=", false); + var peg$e110 = peg$literalExpectation(">=", false); + var peg$e111 = peg$literalExpectation(">", false); + var peg$e112 = peg$literalExpectation("<=", false); + var peg$e113 = peg$literalExpectation("<", false); + var peg$e114 = peg$otherExpectation("word"); + var peg$e115 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false); + var peg$e116 = peg$otherExpectation("whitespace"); + var peg$e117 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false); + var peg$e118 = peg$otherExpectation("quote"); + var peg$e119 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false); + var peg$e120 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false); + var peg$e121 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false); + var peg$e122 = peg$literalExpectation("\u201C", false); + var peg$e123 = peg$literalExpectation("\u201D", false); + var peg$e124 = peg$literalExpectation("\"", false); + var peg$e125 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e126 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e127 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false); + var peg$e128 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false); + var peg$e129 = peg$classExpectation([","], false, false); + var peg$e130 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ","], false, false); var peg$f0 = function(filters) { return applyDefaults(filters); }; var peg$f1 = function(head, tail) { @@ -603,39 +607,41 @@ function peg$parse(input, options) { var peg$f82 = function() { return "groupBankAccount"; }; var peg$f83 = function() { return "groupWithdrawn"; }; var peg$f84 = function() { return "groupWithdrawalID"; }; - var peg$f85 = function() { return "groupCategory"; }; - var peg$f86 = function() { return "groupTag"; }; - var peg$f87 = function() { return "groupMerchant"; }; - var peg$f88 = function() { return "groupmonth"; }; - var peg$f89 = function() { return "groupweek"; }; - var peg$f90 = function() { return "groupyear"; }; - var peg$f91 = function() { return "groupquarter"; }; - var peg$f92 = function() { return "eq"; }; - var peg$f93 = function() { return "neq"; }; - var peg$f94 = function() { return "gte"; }; - var peg$f95 = function() { return "gt"; }; - var peg$f96 = function() { return "lte"; }; - var peg$f97 = function() { return "lt"; }; - var peg$f98 = function(o) { + var peg$f85 = function() { return "groupAmountDebited"; }; + var peg$f86 = function() { return "groupAmountReimbursed"; }; + var peg$f87 = function() { return "groupCategory"; }; + var peg$f88 = function() { return "groupTag"; }; + var peg$f89 = function() { return "groupMerchant"; }; + var peg$f90 = function() { return "groupmonth"; }; + var peg$f91 = function() { return "groupweek"; }; + var peg$f92 = function() { return "groupyear"; }; + var peg$f93 = function() { return "groupquarter"; }; + var peg$f94 = function() { return "eq"; }; + var peg$f95 = function() { return "neq"; }; + var peg$f96 = function() { return "gte"; }; + var peg$f97 = function() { return "gt"; }; + var peg$f98 = function() { return "lte"; }; + var peg$f99 = function() { return "lt"; }; + var peg$f100 = function(o) { if (nameOperator) { expectingNestedQuote = (o === "eq"); // Use simple parser if no valid operator is found } isColumnsContext = false; return o; }; - var peg$f99 = function(chars) { return chars.join("").trim(); }; - var peg$f100 = function() { + var peg$f101 = function(chars) { return chars.join("").trim(); }; + var peg$f102 = function() { isColumnsContext = false; return "and"; }; - var peg$f101 = function() { return expectingNestedQuote; }; - var peg$f102 = function(start, inner, end) { //handle no-breaking space + var peg$f103 = function() { return expectingNestedQuote; }; + var peg$f104 = function(start, inner, end) { //handle no-breaking space return [...start, '"', ...inner, '"', ...end].join(""); }; - var peg$f103 = function(start) {return "“"}; - var peg$f104 = function(start) {return "”"}; - var peg$f105 = function(start) {return "\""}; - var peg$f106 = function(start, inner, end) { + var peg$f105 = function(start) {return "“"}; + var peg$f106 = function(start) {return "”"}; + var peg$f107 = function(start) {return "\""}; + var peg$f108 = function(start, inner, end) { return [...start, '"', ...inner, '"'].join(""); }; var peg$currPos = options.peg$currPos | 0; @@ -2726,19 +2732,25 @@ function peg$parse(input, options) { if (s0 === peg$FAILED) { s0 = peg$parsegroupWithdrawalId(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupCategory(); + s0 = peg$parsegroupAmountDebited(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupTag(); + s0 = peg$parsegroupAmountReimbursed(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupMerchant(); + s0 = peg$parsegroupCategory(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupMonth(); + s0 = peg$parsegroupTag(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupWeek(); + s0 = peg$parsegroupMerchant(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupYear(); + s0 = peg$parsegroupMonth(); if (s0 === peg$FAILED) { - s0 = peg$parsegroupQuarter(); + s0 = peg$parsegroupWeek(); + if (s0 === peg$FAILED) { + s0 = peg$parsegroupYear(); + if (s0 === peg$FAILED) { + s0 = peg$parsegroupQuarter(); + } + } } } } @@ -3687,13 +3699,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupCategory() { + function peg$parsegroupAmountDebited() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 14); + s1 = input.substr(peg$currPos, 20); if (s1.toLowerCase() === peg$c93) { - peg$currPos += 14; + peg$currPos += 20; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e99); } @@ -3724,13 +3736,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupTag() { + function peg$parsegroupAmountReimbursed() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 9); + s1 = input.substr(peg$currPos, 23); if (s1.toLowerCase() === peg$c94) { - peg$currPos += 9; + peg$currPos += 23; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e100); } @@ -3761,7 +3773,7 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupMerchant() { + function peg$parsegroupCategory() { var s0, s1, s2, s3; s0 = peg$currPos; @@ -3798,13 +3810,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupMonth() { + function peg$parsegroupTag() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 11); + s1 = input.substr(peg$currPos, 9); if (s1.toLowerCase() === peg$c96) { - peg$currPos += 11; + peg$currPos += 9; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e102); } @@ -3835,13 +3847,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupWeek() { + function peg$parsegroupMerchant() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 10); + s1 = input.substr(peg$currPos, 14); if (s1.toLowerCase() === peg$c97) { - peg$currPos += 10; + peg$currPos += 14; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e103); } @@ -3872,13 +3884,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupYear() { + function peg$parsegroupMonth() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 10); + s1 = input.substr(peg$currPos, 11); if (s1.toLowerCase() === peg$c98) { - peg$currPos += 10; + peg$currPos += 11; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e104); } @@ -3909,13 +3921,13 @@ function peg$parse(input, options) { return s0; } - function peg$parsegroupQuarter() { + function peg$parsegroupWeek() { var s0, s1, s2, s3; s0 = peg$currPos; - s1 = input.substr(peg$currPos, 13); + s1 = input.substr(peg$currPos, 10); if (s1.toLowerCase() === peg$c99) { - peg$currPos += 13; + peg$currPos += 10; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$e105); } @@ -3946,6 +3958,80 @@ function peg$parse(input, options) { return s0; } + function peg$parsegroupYear() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = input.substr(peg$currPos, 10); + if (s1.toLowerCase() === peg$c100) { + peg$currPos += 10; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e106); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parsewordBoundary(); + peg$silentFails--; + if (s3 !== peg$FAILED) { + peg$currPos = s2; + s2 = undefined; + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f92(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsegroupQuarter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = input.substr(peg$currPos, 13); + if (s1.toLowerCase() === peg$c101) { + peg$currPos += 13; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e107); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parsewordBoundary(); + peg$silentFails--; + if (s3 !== peg$FAILED) { + peg$currPos = s2; + s2 = undefined; + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f93(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + function peg$parseoperator() { var s0, s1; @@ -3960,77 +4046,77 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f92(); + s1 = peg$f94(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c100) { - s1 = peg$c100; + if (input.substr(peg$currPos, 2) === peg$c102) { + s1 = peg$c102; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e107); } + if (peg$silentFails === 0) { peg$fail(peg$e109); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f93(); + s1 = peg$f95(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c101) { - s1 = peg$c101; + if (input.substr(peg$currPos, 2) === peg$c103) { + s1 = peg$c103; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e108); } + if (peg$silentFails === 0) { peg$fail(peg$e110); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f94(); + s1 = peg$f96(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 62) { - s1 = peg$c102; + s1 = peg$c104; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e109); } + if (peg$silentFails === 0) { peg$fail(peg$e111); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f95(); + s1 = peg$f97(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c103) { - s1 = peg$c103; + if (input.substr(peg$currPos, 2) === peg$c105) { + s1 = peg$c105; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e110); } + if (peg$silentFails === 0) { peg$fail(peg$e112); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f96(); + s1 = peg$f98(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c104; + s1 = peg$c106; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e111); } + if (peg$silentFails === 0) { peg$fail(peg$e113); } } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f97(); + s1 = peg$f99(); } s0 = s1; } @@ -4041,7 +4127,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e106); } + if (peg$silentFails === 0) { peg$fail(peg$e108); } } return s0; @@ -4054,7 +4140,7 @@ function peg$parse(input, options) { s1 = peg$parseoperator(); if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f98(s1); + s1 = peg$f100(s1); } s0 = s1; @@ -4072,7 +4158,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } if (s2 !== peg$FAILED) { while (s2 !== peg$FAILED) { @@ -4082,7 +4168,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } } } else { @@ -4090,13 +4176,13 @@ function peg$parse(input, options) { } if (s1 !== peg$FAILED) { peg$savedPos = s0; - s1 = peg$f99(s1); + s1 = peg$f101(s1); } s0 = s1; peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e112); } + if (peg$silentFails === 0) { peg$fail(peg$e114); } } return s0; @@ -4108,7 +4194,7 @@ function peg$parse(input, options) { s0 = peg$currPos; s1 = peg$parse_(); peg$savedPos = s0; - s1 = peg$f100(); + s1 = peg$f102(); s0 = s1; return s0; @@ -4124,7 +4210,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } while (s1 !== peg$FAILED) { s0.push(s1); @@ -4133,12 +4219,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e115); } + if (peg$silentFails === 0) { peg$fail(peg$e117); } } } peg$silentFails--; s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e114); } + if (peg$silentFails === 0) { peg$fail(peg$e116); } return s0; } @@ -4148,7 +4234,7 @@ function peg$parse(input, options) { s0 = peg$currPos; peg$savedPos = peg$currPos; - s1 = peg$f101(); + s1 = peg$f103(); if (s1) { s1 = undefined; } else { @@ -4185,7 +4271,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4194,7 +4280,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } } s2 = input.charAt(peg$currPos); @@ -4202,7 +4288,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s2 !== peg$FAILED) { s3 = []; @@ -4211,7 +4297,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -4220,7 +4306,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } } s4 = input.charAt(peg$currPos); @@ -4228,7 +4314,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s4 !== peg$FAILED) { s5 = []; @@ -4237,7 +4323,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } while (s6 !== peg$FAILED) { s5.push(s6); @@ -4246,11 +4332,11 @@ function peg$parse(input, options) { peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e113); } + if (peg$silentFails === 0) { peg$fail(peg$e115); } } } peg$savedPos = s0; - s0 = peg$f102(s1, s3, s5); + s0 = peg$f104(s1, s3, s5); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -4262,7 +4348,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } return s0; @@ -4279,7 +4365,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4288,7 +4374,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e117); } + if (peg$silentFails === 0) { peg$fail(peg$e119); } } } s2 = input.charAt(peg$currPos); @@ -4296,7 +4382,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s2 !== peg$FAILED) { s3 = []; @@ -4305,7 +4391,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } if (s4 === peg$FAILED) { s4 = peg$currPos; @@ -4321,15 +4407,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8220) { - s6 = peg$c105; + s6 = peg$c107; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e120); } + if (peg$silentFails === 0) { peg$fail(peg$e122); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f103(s1); + s4 = peg$f105(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4352,15 +4438,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8221) { - s6 = peg$c106; + s6 = peg$c108; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e121); } + if (peg$silentFails === 0) { peg$fail(peg$e123); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f104(s1); + s4 = peg$f106(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4383,15 +4469,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s6 = peg$c107; + s6 = peg$c109; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e122); } + if (peg$silentFails === 0) { peg$fail(peg$e124); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f105(s1); + s4 = peg$f107(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4410,7 +4496,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e119); } + if (peg$silentFails === 0) { peg$fail(peg$e121); } } if (s4 === peg$FAILED) { s4 = peg$currPos; @@ -4426,15 +4512,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8220) { - s6 = peg$c105; + s6 = peg$c107; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e120); } + if (peg$silentFails === 0) { peg$fail(peg$e122); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f103(s1); + s4 = peg$f105(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4457,15 +4543,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8221) { - s6 = peg$c106; + s6 = peg$c108; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e121); } + if (peg$silentFails === 0) { peg$fail(peg$e123); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f104(s1); + s4 = peg$f106(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4488,15 +4574,15 @@ function peg$parse(input, options) { } if (s5 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s6 = peg$c107; + s6 = peg$c109; peg$currPos++; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e122); } + if (peg$silentFails === 0) { peg$fail(peg$e124); } } if (s6 !== peg$FAILED) { peg$savedPos = s4; - s4 = peg$f105(s1); + s4 = peg$f107(s1); } else { peg$currPos = s4; s4 = peg$FAILED; @@ -4512,7 +4598,7 @@ function peg$parse(input, options) { s4 = peg$parseclosingQuote(); if (s4 !== peg$FAILED) { peg$savedPos = s0; - s0 = peg$f106(s1, s3, s4); + s0 = peg$f108(s1, s3, s4); } else { peg$currPos = s0; s0 = peg$FAILED; @@ -4524,7 +4610,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e116); } + if (peg$silentFails === 0) { peg$fail(peg$e118); } } return s0; @@ -4539,7 +4625,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e118); } + if (peg$silentFails === 0) { peg$fail(peg$e120); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -4577,7 +4663,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e123); } + if (peg$silentFails === 0) { peg$fail(peg$e125); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4586,7 +4672,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e123); } + if (peg$silentFails === 0) { peg$fail(peg$e125); } } } s2 = []; @@ -4595,7 +4681,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e124); } + if (peg$silentFails === 0) { peg$fail(peg$e126); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -4604,7 +4690,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e124); } + if (peg$silentFails === 0) { peg$fail(peg$e126); } } } s3 = []; @@ -4613,7 +4699,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e125); } + if (peg$silentFails === 0) { peg$fail(peg$e127); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -4622,7 +4708,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e125); } + if (peg$silentFails === 0) { peg$fail(peg$e127); } } } s4 = peg$parseoperator(); @@ -4641,7 +4727,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e126); } + if (peg$silentFails === 0) { peg$fail(peg$e128); } } while (s2 !== peg$FAILED) { s1.push(s2); @@ -4650,7 +4736,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e126); } + if (peg$silentFails === 0) { peg$fail(peg$e128); } } } s2 = peg$currPos; @@ -4697,7 +4783,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e127); } + if (peg$silentFails === 0) { peg$fail(peg$e129); } } } } @@ -4713,7 +4799,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e128); } + if (peg$silentFails === 0) { peg$fail(peg$e130); } } if (s0 === peg$FAILED) { s0 = peg$currPos; diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 08f964c76a80..6db0bf69bb30 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -371,6 +371,10 @@ const transactionWithdrawalIDGroupColumnNamesToSortingProperty: TransactionWithd [CONST.SEARCH.TABLE_COLUMNS.WITHDRAWN]: 'debitPosted' as const, [CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWAL_STATUS]: 'state' as const, [CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID]: 'formattedWithdrawalID' as const, + // Both the backend page selection and this local sort rank the amounts as stored, without converting between + // currencies, so a group can outrank one that is worth more in another currency. + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: 'debitedAmount' as const, + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: 'creditedAmount' as const, ...transactionGroupBaseSortingProperties, }; @@ -4522,6 +4526,10 @@ function getSearchColumnTranslationKey(column: SearchSortBy): TranslationPaths { return 'common.expenses'; case CONST.SEARCH.TABLE_COLUMNS.GROUP_TOTAL: return 'common.total'; + case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED: + return 'common.amountDebited'; + case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED: + return 'common.amountReimbursed'; case CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID: return 'common.withdrawalID'; case CONST.SEARCH.TABLE_COLUMNS.SUBMITTER_USER_ID: @@ -5876,6 +5884,30 @@ function getPolicyTagsForPolicyID(policyTags: PolicyTagsLookup | undefined, poli return policyTagsKey ? policyTags[policyTagsKey] : undefined; } +// Only settlements that converted currencies carry these amounts, so each column stays hidden until a group reports one. +const conversionAmountGroupColumns = { + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: {amount: 'debitedAmount', currency: 'debitedCurrency'}, + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: {amount: 'creditedAmount', currency: 'creditedCurrency'}, +} as const satisfies Partial>; + +function isConversionAmountGroupColumn(column: SearchColumnType): column is keyof typeof conversionAmountGroupColumns { + return column in conversionAmountGroupColumns; +} + +function hasGroupWithConversionAmount(column: keyof typeof conversionAmountGroupColumns, data: OnyxTypes.SearchResults['data']): boolean { + const {amount, currency} = conversionAmountGroupColumns[column]; + return Object.keys(data).some((key) => { + if (!isGroupEntry(key)) { + return false; + } + + const group: Partial = data[key]; + + // getWithdrawalIDSections drops groups without an account number, so a column keyed off one would have no row to fill it. + return !!group.accountNumber && !!group[amount] && !!group[currency]; + }); +} + /** * Determines what columns to show based on available data * @param isExpenseReportView: true when we are inside an expense report view, false if we're in the Reports page. @@ -5897,6 +5929,7 @@ function getColumnsToShow({ shouldUseStrictDefaultExpenseColumns = false, isPolicyTaxEnabled = false, fallbackPolicyID, + sortBy, }: { currentAccountID: number | undefined; data: OnyxTypes.SearchResults['data'] | OnyxTypes.Transaction[]; @@ -5913,6 +5946,7 @@ function getColumnsToShow({ shouldUseStrictDefaultExpenseColumns?: boolean; isPolicyTaxEnabled?: boolean; fallbackPolicyID?: string; + sortBy?: SearchSortBy; }): SearchColumnType[] { const reportCustomColumns = new Set([ CONST.SEARCH.TABLE_COLUMNS.SUBMITTER_USER_ID, @@ -6034,7 +6068,13 @@ function getColumnsToShow({ result.push(col); } - return result; + if (Array.isArray(data)) { + return result; + } + + // The column the results are sorted by has to stay, even with nothing to show in it. Both the header and the + // Sort by option come from this list, so dropping it would leave the sort applied with no way to change it. + return result.filter((column) => !isConversionAmountGroupColumn(column) || column === sortBy || hasGroupWithConversionAmount(column, data)); } } diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index b62a7e633c85..fd6fdae7aea4 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -2014,6 +2014,11 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ case CONST.SEARCH.TABLE_COLUMNS.GROUP_EXPENSES: columnWidth = {...getWidthStyle(variables.w130)}; break; + case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED: + case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED: + // Fixed width: wide enough for the long headers these columns carry, so no amount-based widening is needed. + columnWidth = {...getWidthStyle(variables.w130), ...styles.alignItemsEnd}; + break; case CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE_TOTAL: case CONST.SEARCH.TABLE_COLUMNS.NON_REIMBURSABLE_TOTAL: case CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT: diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index e48db2a3a640..4ee77a699e9f 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -194,6 +194,18 @@ type SearchWithdrawalIDGroup = { /** Settlement state (5/6/7=failed, 8=cleared, others=pending) */ state: number; + /** What the company was debited, when the settlement converted currencies */ + debitedAmount?: number; + + /** Currency the company was debited in */ + debitedCurrency?: string; + + /** What the employee was credited, when the settlement converted currencies */ + creditedAmount?: number; + + /** Currency the employee was credited in */ + creditedCurrency?: string; + /** Workspace ID for the grouped settlement */ policyID?: string; diff --git a/tests/unit/Search/ColumnAvailabilityTest.ts b/tests/unit/Search/ColumnAvailabilityTest.ts index fa1578228a41..a28fdb55ec0c 100644 --- a/tests/unit/Search/ColumnAvailabilityTest.ts +++ b/tests/unit/Search/ColumnAvailabilityTest.ts @@ -54,6 +54,8 @@ describe('Column availability single source of truth', () => { TABLE_COLUMNS.GROUP_YEAR, TABLE_COLUMNS.GROUP_QUARTER, TABLE_COLUMNS.GROUP_WITHDRAWAL_STATUS, + TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, ]); test('every TABLE_COLUMNS value is classified in COLUMN_AVAILABILITY or owned by another surface', () => { diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 8f5a98260be8..3df803d535fd 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -16,7 +16,7 @@ import type { TransactionYearGroupListItemType, } from '@components/Search/SearchList/ListItem/types'; import {getExpenseHeaders} from '@components/Search/SearchTableHeader'; -import type {SelectedTransactionInfo} from '@components/Search/types'; +import type {SearchColumnType, SelectedTransactionInfo, SortOrder} from '@components/Search/types'; import Navigation from '@navigation/Navigation'; @@ -6920,6 +6920,41 @@ describe('SearchUIUtils', () => { ).toStrictEqual(transactionWithdrawalIDGroupListItemsSorted); }); + it('should sort withdrawal-id groups by each conversion amount, leaving the settlements that did not convert at the empty end', () => { + const withConversion = (keyForList: string, debitedAmount?: number, creditedAmount?: number): TransactionWithdrawalIDGroupListItemType => ({ + bankName: CONST.BANK_NAMES.CHASE, + entryID, + accountNumber, + debitPosted: '2025-08-12 17:11:22', + count: 4, + currency: 'USD', + total: 40, + state: 8, + groupedBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID, + formattedWithdrawalID: '5', + transactions: [], + transactionsQueryJSON: undefined, + shouldShowYearWithdrawn: true, + keyForList, + ...(debitedAmount ? {debitedAmount, debitedCurrency: 'USD'} : {}), + ...(creditedAmount ? {creditedAmount, creditedCurrency: 'GBP'} : {}), + }); + const domestic = withConversion('group_domestic'); + const smallConversion = withConversion('group_small', 1694, 1340); + const largeConversion = withConversion('group_large', 32200, 26886); + const groups = [smallConversion, domestic, largeConversion]; + + const sortGroups = (sortBy: SearchColumnType, sortOrder: SortOrder) => + SearchUIUtils.getSortedSections(CONST.SEARCH.DATA_TYPES.EXPENSE, [...groups], localeCompare, translateLocal, sortBy, sortOrder, CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID).map( + (group) => group.keyForList, + ); + + expect(sortGroups(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, CONST.SEARCH.SORT_ORDER.ASC)).toStrictEqual(['group_domestic', 'group_small', 'group_large']); + expect(sortGroups(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, CONST.SEARCH.SORT_ORDER.DESC)).toStrictEqual(['group_large', 'group_small', 'group_domestic']); + expect(sortGroups(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, CONST.SEARCH.SORT_ORDER.ASC)).toStrictEqual(['group_domestic', 'group_small', 'group_large']); + expect(sortGroups(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, CONST.SEARCH.SORT_ORDER.DESC)).toStrictEqual(['group_large', 'group_small', 'group_domestic']); + }); + it('should sort category group data when type is EXPENSE and groupBy is category', () => { expect( SearchUIUtils.getSortedSections( @@ -9615,6 +9650,94 @@ describe('SearchUIUtils', () => { expect(result).toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_FROM); }); + test('Should only show the conversion amount columns for withdrawal groups that converted currencies', () => { + const domesticGroup = { + entryID: 1, + count: 1, + total: -10000, + currency: 'USD', + accountNumber: '1234', + bankName: CONST.BANK_NAMES.CHASE, + debitPosted: '2026-01-02', + state: 8, + }; + const crossBorderGroup = { + ...domesticGroup, + entryID: 2, + debitedAmount: 10000, + debitedCurrency: 'USD', + creditedAmount: 9200, + creditedCurrency: 'EUR', + }; + + // @ts-expect-error minimal dataset for getColumnsToShow + const domesticData: OnyxTypes.SearchResults['data'] = {[`group_${domesticGroup.entryID}`]: domesticGroup}; + const crossBorderData: OnyxTypes.SearchResults['data'] = {...domesticData, [`group_${crossBorderGroup.entryID}`]: crossBorderGroup}; + + const domesticColumns = SearchUIUtils.getColumnsToShow({currentAccountID: 1, data: domesticData, visibleColumns: [], groupBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID}); + expect(domesticColumns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED); + expect(domesticColumns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED); + + const crossBorderColumns = SearchUIUtils.getColumnsToShow({currentAccountID: 1, data: crossBorderData, visibleColumns: [], groupBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID}); + expect(crossBorderColumns).toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED); + expect(crossBorderColumns).toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED); + + // A group with no account number never reaches the list, so its amounts must not open a column either. + const unrenderedData: OnyxTypes.SearchResults['data'] = {...domesticData, [`group_${crossBorderGroup.entryID}`]: {...crossBorderGroup, accountNumber: ''}}; + const unrenderedColumns = SearchUIUtils.getColumnsToShow({currentAccountID: 1, data: unrenderedData, visibleColumns: [], groupBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID}); + expect(unrenderedColumns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED); + expect(unrenderedColumns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED); + }); + + test('Should hide a conversion amount column when its currency is missing', () => { + const groupMissingCreditedCurrency = { + entryID: 3, + count: 1, + total: -10000, + currency: 'USD', + accountNumber: '1234', + bankName: CONST.BANK_NAMES.CHASE, + debitPosted: '2026-01-02', + state: 8, + debitedAmount: 10000, + debitedCurrency: 'USD', + creditedAmount: 9200, + }; + + // @ts-expect-error minimal dataset for getColumnsToShow + const data: OnyxTypes.SearchResults['data'] = {[`group_${groupMissingCreditedCurrency.entryID}`]: groupMissingCreditedCurrency}; + + const columns = SearchUIUtils.getColumnsToShow({currentAccountID: 1, data, visibleColumns: [], groupBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID}); + expect(columns).toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED); + expect(columns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED); + }); + + test('Should keep the conversion amount column the groups are sorted by', () => { + const domesticGroup = { + entryID: 4, + count: 1, + total: -10000, + currency: 'USD', + accountNumber: '1234', + bankName: CONST.BANK_NAMES.CHASE, + debitPosted: '2026-01-02', + state: 8, + }; + + // @ts-expect-error minimal dataset for getColumnsToShow + const data: OnyxTypes.SearchResults['data'] = {[`group_${domesticGroup.entryID}`]: domesticGroup}; + + const columns = SearchUIUtils.getColumnsToShow({ + currentAccountID: 1, + data, + visibleColumns: [], + groupBy: CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID, + sortBy: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + }); + expect(columns).toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED); + expect(columns).not.toContain(CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED); + }); + test('Should hide To for strict default expense columns', () => { const baseTransaction = searchResults.data[`transactions_${transactionID}`]; const tx = {