From e1790951c6d2a6ecd425be4281d118ebfc6a58b0 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 04:44:42 +0530 Subject: [PATCH 01/14] Add the amount debited and amount reimbursed columns for withdrawal groups --- src/CONST/index.ts | 8 + src/languages/en.ts | 2 + src/libs/SearchParser/autocompleteParser.js | 424 ++++++++++++-------- src/libs/SearchParser/baseRules.peggy | 4 + src/libs/SearchParser/searchParser.js | 424 ++++++++++++-------- src/types/onyx/SearchResults.ts | 12 + tests/unit/Search/ColumnAvailabilityTest.ts | 2 + 7 files changed, 538 insertions(+), 338 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 44ec0632b64b..f8873cc6ce8a 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -7030,6 +7030,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: { @@ -7108,6 +7110,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], @@ -7228,6 +7232,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', @@ -7448,6 +7454,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_MODIFIER: 'Not', diff --git a/src/languages/en.ts b/src/languages/en.ts index c395ce79f068..f2d175a57b89 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -430,6 +430,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/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/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index 2ab876d872d1..5e3661305ff7 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -196,6 +196,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; }; /** Model of category grouped search result */ 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', () => { From 1174e9d29b49a032a12cc8eaab991ddd44d0e9e6 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 04:44:48 +0530 Subject: [PATCH 02/14] Render each conversion amount in its own currency and hide the columns until a settlement converts --- .../ListItem/WithdrawalIDListItemHeader.tsx | 30 ++++++++++ src/components/Search/SearchTableHeader.tsx | 36 +++++++----- src/libs/SearchUIUtils.ts | 37 +++++++++++- src/styles/utils/index.ts | 4 ++ tests/unit/Search/SearchUIUtilsTest.ts | 57 +++++++++++++++++++ 5 files changed, 150 insertions(+), 14 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx index 7327f9aa8b29..53b439494ca8 100644 --- a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx +++ b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx @@ -93,6 +93,10 @@ function WithdrawalIDListItemHeaderImpl({ withdrawalIDItem.debitPosted, DateUtils.doesDateBelongToAPastYear(withdrawalIDItem.debitPosted) ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, ); + // A settlement that converted currencies moved a different amount on each side, each in its own currency, so + // neither side is shown without the currency it is denominated in. + const {debitedAmount, debitedCurrency, creditedAmount, creditedCurrency} = withdrawalIDItem; + const badgeProps = getSettlementStatusBadgeProps(withdrawalIDItem.state, translate, theme); const settlementStatus = getSettlementStatus(withdrawalIDItem.state); const statusBadge = !!badgeProps && ( @@ -177,6 +181,32 @@ function WithdrawalIDListItemHeaderImpl({ ), + [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 [ @@ -408,7 +407,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: false, + }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, + translationKey: 'common.amountReimbursed', + isColumnSortable: false, + }, + groupTotalHeader, ]; case CONST.SEARCH.GROUP_BY.CATEGORY: return [ diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 49d8b9402457..3c54df566c05 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -429,6 +429,11 @@ const nonSortableColumns = new Set([ CONST.SEARCH.TABLE_COLUMNS.ACTION, CONST.SEARCH.TABLE_COLUMNS.IN, CONST.SEARCH.TABLE_COLUMNS.AVATAR, + + // Each side of a conversion is denominated in its own currency, so ordering the raw numbers would rank + // amounts that are not comparable. + CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, + CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, ]); function isValidExpenseStatus(status: unknown): status is ValueOf { @@ -4459,6 +4464,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: @@ -5768,6 +5777,32 @@ 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 hasConversionAmount(column: SearchColumnType, data: OnyxTypes.SearchResults['data'] | OnyxTypes.Transaction[]): boolean { + if (!isConversionAmountGroupColumn(column) || Array.isArray(data)) { + return !isConversionAmountGroupColumn(column); + } + + const {amount, currency} = conversionAmountGroupColumns[column]; + return Object.keys(data).some((key) => { + if (!isGroupEntry(key)) { + return false; + } + + const group: Partial = data[key]; + return !!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. @@ -5926,7 +5961,7 @@ function getColumnsToShow({ result.push(col); } - return result; + return result.filter((column) => hasConversionAmount(column, data)); } } diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 89716ac31b22..5fe57a117f55 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1941,6 +1941,10 @@ 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: + columnWidth = {...getWidthStyle(isAmountColumnWide ? variables.w130 : variables.w96), ...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/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index a018ccff1e9b..560e15584b7c 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -9473,6 +9473,63 @@ 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}; + // @ts-expect-error minimal dataset for getColumnsToShow + 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); + }); + + 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 hide To for strict default expense columns', () => { const baseTransaction = searchResults.data[`transactions_${transactionID}`]; const tx = { From b6792696db5397d052a9ffe916539c0c6387c7d1 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 05:12:51 +0530 Subject: [PATCH 03/14] Allow sorting the reconciliation dashboard by either conversion amount --- src/components/Search/SearchTableHeader.tsx | 2 -- src/libs/SearchUIUtils.ts | 7 ++----- tests/unit/Search/SearchUIUtilsTest.ts | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/Search/SearchTableHeader.tsx b/src/components/Search/SearchTableHeader.tsx index 5dce37f9bc7b..13c736022193 100644 --- a/src/components/Search/SearchTableHeader.tsx +++ b/src/components/Search/SearchTableHeader.tsx @@ -411,12 +411,10 @@ const getTransactionGroupHeaders = (groupBy: SearchGroupBy, icons: SearchHeaderI { columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, translationKey: 'common.amountDebited', - isColumnSortable: false, }, { columnName: CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, translationKey: 'common.amountReimbursed', - isColumnSortable: false, }, groupTotalHeader, ]; diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 3c54df566c05..2d24889e3e98 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -367,6 +367,8 @@ 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, + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: 'debitedAmount' as const, + [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: 'creditedAmount' as const, ...transactionGroupBaseSortingProperties, }; @@ -429,11 +431,6 @@ const nonSortableColumns = new Set([ CONST.SEARCH.TABLE_COLUMNS.ACTION, CONST.SEARCH.TABLE_COLUMNS.IN, CONST.SEARCH.TABLE_COLUMNS.AVATAR, - - // Each side of a conversion is denominated in its own currency, so ordering the raw numbers would rank - // amounts that are not comparable. - CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED, - CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED, ]); function isValidExpenseStatus(status: unknown): status is ValueOf { diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 560e15584b7c..63a052e9c6e5 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -9495,7 +9495,6 @@ describe('SearchUIUtils', () => { // @ts-expect-error minimal dataset for getColumnsToShow const domesticData: OnyxTypes.SearchResults['data'] = {[`group_${domesticGroup.entryID}`]: domesticGroup}; - // @ts-expect-error minimal dataset for getColumnsToShow 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}); From 3d7bcaccf9314307824563c95cddca6ac860361a Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 05:12:51 +0530 Subject: [PATCH 04/14] Keep the conversion amount headers inside their own columns --- src/components/Search/SortableTableHeader.tsx | 3 ++- src/styles/utils/index.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) 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/styles/utils/index.ts b/src/styles/utils/index.ts index 5fe57a117f55..d942b7f69744 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1943,7 +1943,8 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ break; case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED: case CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED: - columnWidth = {...getWidthStyle(isAmountColumnWide ? variables.w130 : variables.w96), ...styles.alignItemsEnd}; + // 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: From 45c5e4a8983da317c10635237b82eddf91cf7df1 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 06:26:23 +0530 Subject: [PATCH 05/14] Let the two conversion amount columns be sorted SortableTableHeader only makes a header pressable when isColumnSortable is set, so without it the columns rendered as plain labels and the sort Auth supports could not be reached. Co-Authored-By: Claude Opus 5 (1M context) --- src/components/Search/SearchTableHeader.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Search/SearchTableHeader.tsx b/src/components/Search/SearchTableHeader.tsx index 13c736022193..d6008df1f2b5 100644 --- a/src/components/Search/SearchTableHeader.tsx +++ b/src/components/Search/SearchTableHeader.tsx @@ -411,10 +411,12 @@ const getTransactionGroupHeaders = (groupBy: SearchGroupBy, icons: SearchHeaderI { 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, ]; @@ -426,6 +428,7 @@ const getTransactionGroupHeaders = (groupBy: SearchGroupBy, icons: SearchHeaderI isColumnSortable: true, }, ...commonGroupHeaders, + x, ]; case CONST.SEARCH.GROUP_BY.MERCHANT: return [ From 09a5082271231253ac1ff691b37d9baf642f3345 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 06:26:40 +0530 Subject: [PATCH 06/14] Keep the backend order for the conversion amount sorts getSortedData re-sorts the page by the mapped property, which for these two columns is a raw amount in whichever currency that settlement used. Ranking GBP 10250 against USD 12000 that way puts them in the wrong order. Unmapped columns fall through with the data untouched, which is the order Auth already computed from a common-currency sort key. Co-Authored-By: Claude Opus 5 (1M context) --- src/libs/SearchUIUtils.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 2d24889e3e98..6bf9262fe7e4 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -367,8 +367,9 @@ 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, - [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_DEBITED]: 'debitedAmount' as const, - [CONST.SEARCH.TABLE_COLUMNS.GROUP_AMOUNT_REIMBURSED]: 'creditedAmount' as const, + // The conversion amounts are each denominated in their own currency, so the backend ranks them by a hidden key + // that converts every group to one currency. Leaving them unmapped keeps that order instead of re-sorting the + // page by raw numbers that are not comparable. ...transactionGroupBaseSortingProperties, }; From 4754bb4207cddb2fbc9cef4ca5cccf8e68c245bd Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 06:30:04 +0530 Subject: [PATCH 07/14] Translate the two new column headers typecheck and TranslateTest both fail on a key that only exists in en.ts. The generateTranslations bot skips pull requests from forks, so these are written by hand. Co-Authored-By: Claude Opus 5 (1M context) --- src/languages/de.ts | 2 ++ src/languages/es.ts | 2 ++ src/languages/fr.ts | 2 ++ src/languages/it.ts | 2 ++ src/languages/ja.ts | 2 ++ src/languages/nl.ts | 2 ++ src/languages/pl.ts | 2 ++ src/languages/pt-BR.ts | 2 ++ src/languages/zh-hans.ts | 2 ++ 9 files changed, 18 insertions(+) diff --git a/src/languages/de.ts b/src/languages/de.ts index ce65a8b932a3..f8088d63b64e 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -402,6 +402,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/es.ts b/src/languages/es.ts index 7f1b9fed1c00..214bbfacf524 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -459,6 +459,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 4deca52d75f1..27bbb61f24b6 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -401,6 +401,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 fa42e6be6a40..dedcd5339f86 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -402,6 +402,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 bb7736a5d2e4..1436caf1f776 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -401,6 +401,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 4167f2dcda00..9967dd1b9249 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -401,6 +401,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 62b508c159b8..411ef9dcb15c 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -401,6 +401,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 16998d7b1e67..f316a9c844dd 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -401,6 +401,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 a71f2d2bec1a..fb74163dd0a5 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -401,6 +401,8 @@ const translations: TranslationDeepObject = { longReportID: '长报表 ID', withdrawalID: '提现编号', internationalReimbursementIDs: '国际报销 ID', + amountDebited: '扣款金额', + amountReimbursed: '报销金额', withdrawalStatus: '提现状态', paidStatus: '已付款状态', bankAccounts: '银行账户', From ad783d46011427882fabb76f061ac71e2c6a3a92 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 06:49:00 +0530 Subject: [PATCH 08/14] Drop a stray token from the category headers The list is built at module scope, so the name resolves the moment the file loads and grouping by category throws instead of rendering. --- src/components/Search/SearchTableHeader.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Search/SearchTableHeader.tsx b/src/components/Search/SearchTableHeader.tsx index d6008df1f2b5..e46193c25eef 100644 --- a/src/components/Search/SearchTableHeader.tsx +++ b/src/components/Search/SearchTableHeader.tsx @@ -428,7 +428,6 @@ const getTransactionGroupHeaders = (groupBy: SearchGroupBy, icons: SearchHeaderI isColumnSortable: true, }, ...commonGroupHeaders, - x, ]; case CONST.SEARCH.GROUP_BY.MERCHANT: return [ From c89bf34cb433cfedf78a9f26f60e41ac84c76dd9 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 28 Jul 2026 06:49:01 +0530 Subject: [PATCH 09/14] Say the column visibility rule the way the report list says it The helper answered "does this column have data" for every column, which read as a double negative for the ones it knows nothing about. Bail out on a transaction array first, then ask the question only of the two conversion columns, matching the expense report branch above. --- .../ListItem/WithdrawalIDListItemHeader.tsx | 3 +-- src/libs/SearchUIUtils.ts | 17 ++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx index 53b439494ca8..67f72a025cdc 100644 --- a/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx +++ b/src/components/Search/SearchList/ListItem/WithdrawalIDListItemHeader.tsx @@ -93,8 +93,6 @@ function WithdrawalIDListItemHeaderImpl({ withdrawalIDItem.debitPosted, DateUtils.doesDateBelongToAPastYear(withdrawalIDItem.debitPosted) ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, ); - // A settlement that converted currencies moved a different amount on each side, each in its own currency, so - // neither side is shown without the currency it is denominated in. const {debitedAmount, debitedCurrency, creditedAmount, creditedCurrency} = withdrawalIDItem; const badgeProps = getSettlementStatusBadgeProps(withdrawalIDItem.state, translate, theme); @@ -181,6 +179,7 @@ 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]: (