diff --git a/bindings/engine.i b/bindings/engine.i index 0546363c686..20158bf52f4 100644 --- a/bindings/engine.i +++ b/bindings/engine.i @@ -129,19 +129,27 @@ static const GncGUID * gncBudgetGetGUID(GncBudget *x) SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date, time64 end_date, gnc_commodity *comm, bool sort) { - auto match = [use_end_date, end_date, comm](const Split* s) -> bool + SplitsVec rv; + + auto maybe_accumulate = [&rv, comm](auto s) { - if (xaccSplitGetReconcile (s) == VREC) return false; - auto trans{xaccSplitGetParent (s)}; - if (use_end_date && xaccTransGetDate(trans) > end_date) return false; - auto txn_comm{xaccTransGetCurrency (trans)}; + auto txn_comm{xaccTransGetCurrency (xaccSplitGetParent (s))}; auto acc_comm{xaccAccountGetCommodity (xaccSplitGetAccount (s))}; - return (txn_comm != acc_comm) && (!comm || comm == txn_comm || comm == acc_comm); + if ((xaccSplitGetReconcile (s) != VREC) && + (txn_comm != acc_comm) && + (!comm || comm == txn_comm || comm == acc_comm)) + rv.push_back (s); }; - std::vector rv; - auto maybe_accumulate_split = [&rv, match](auto s){ if (match(s)) rv.push_back (s); }; - for (const auto acc : accounts) - gnc_account_foreach_split (acc, maybe_accumulate_split, true); + + std::function scan_account; + if (use_end_date) + scan_account = [end_date, maybe_accumulate](auto acc) + { gnc_account_foreach_split_until_date (acc, end_date, maybe_accumulate); }; + else + scan_account = [maybe_accumulate](auto acc) + { gnc_account_foreach_split (acc, maybe_accumulate, false); }; + + std::for_each (accounts.begin(), accounts.end(), scan_account); if (sort) std::sort (rv.begin(), rv.end(), [](auto a, auto b){ return xaccSplitOrder (a, b) < 0; }); return rv; diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp index 589593b799a..2b451281485 100644 --- a/libgnucash/engine/Account.cpp +++ b/libgnucash/engine/Account.cpp @@ -1151,6 +1151,22 @@ gnc_account_foreach_split (const Account *acc, std::function func, std::for_each(splits.begin(), splits.end(), func); } +void +gnc_account_foreach_split_until_date (const Account *acc, time64 end_date, + std::function f) +{ + if (!GNC_IS_ACCOUNT (acc)) + return; + + auto after_date = [](time64 end_date, auto s) -> bool + { return (xaccTransGetDate (xaccSplitGetParent (s)) > end_date); }; + + auto splits{GET_PRIVATE(acc)->splits}; + auto after_date_iter = std::upper_bound (splits.begin(), splits.end(), end_date, after_date); + std::for_each (splits.begin(), after_date_iter, f); +} + + Split* gnc_account_find_split (const Account *acc, std::function predicate, bool reverse) diff --git a/libgnucash/engine/Account.hpp b/libgnucash/engine/Account.hpp index b246bf68853..332e45ff7b7 100644 --- a/libgnucash/engine/Account.hpp +++ b/libgnucash/engine/Account.hpp @@ -43,6 +43,9 @@ const SplitsVec xaccAccountGetSplits (const Account*); void gnc_account_foreach_split (const Account*, std::function, bool); +void gnc_account_foreach_split_until_date (const Account *acc, time64 end_date, + std::function f); + /** scans account split list (in forward or reverse order) until * predicate split->bool returns true. Maybe return the split. *