@@ -66,6 +66,22 @@ using AccountVec = std::vector<Account*>;
66
66
SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date,
67
67
time64 end_date, gnc_commodity *comm, bool sort);
68
68
69
+ /* scans account splits, in posted date order, calling split_fn(split)
70
+ at each split and accumulate the result at each date in the SCM
71
+ list dates into a new SCM list. Parameters are:
72
+
73
+ acc the account
74
+ dates the SCM list of posted dates, assumed to be in chronological order
75
+ init the result to be pushed into the result for dates prior to first split date
76
+ split_fn the split->elt procedure whose result of (split_fn split) will be pushed
77
+ into the returned SCM list */
78
+ SCM gnc_account_accumulate_to_dates (const Account *acc, SCM dates,
79
+ SCM split_fn, SCM init);
80
+
81
+ /* as above, but the split_to_date function to use a different date order. */
82
+ SCM gnc_account_accumulate_to_dates (const Account *acc, SCM dates,
83
+ SCM split_fn, SCM init, SCM split_to_date);
84
+
69
85
AccountVec gnc_accounts_and_all_descendants (AccountVec accounts);
70
86
71
87
extern " C"
@@ -160,6 +176,51 @@ SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date
160
176
return rv;
161
177
}
162
178
179
+ static SCM
180
+ accumulate_splits_by_dates (const SplitsVec& splits, SCM dates, SCM result,
181
+ std::function<bool (Split*,SCM)> no_later_than_date,
182
+ std::function<SCM (Split*)> get_result)
183
+ {
184
+ SCM rv = SCM_EOL;
185
+ auto splits_it = splits.begin ();
186
+ for (; !scm_is_null (dates); dates = scm_cdr (dates))
187
+ {
188
+ while (splits_it != splits.end () && no_later_than_date (*splits_it, scm_car (dates)))
189
+ result = get_result (*splits_it++);
190
+
191
+ rv = scm_cons (result, rv);
192
+ }
193
+ return scm_reverse_x (rv, SCM_EOL);
194
+ }
195
+
196
+ SCM
197
+ gnc_account_accumulate_to_dates (const Account *acc, SCM dates,
198
+ SCM split_fn, SCM init)
199
+ {
200
+ const auto & splits = xaccAccountGetSplits (acc);
201
+ auto get_result = [&](Split* s) -> SCM { return scm_call_1 (split_fn, gnc_split_to_scm (s)); };
202
+ auto no_later_than_date = [&](Split* s, SCM date) -> bool
203
+ { return xaccTransGetDate (xaccSplitGetParent (s)) <= scm_to_int64 (date); };
204
+
205
+ return accumulate_splits_by_dates (splits, dates, init, no_later_than_date, get_result);
206
+ }
207
+
208
+ SCM
209
+ gnc_account_accumulate_to_dates (const Account *acc, SCM dates,
210
+ SCM split_fn, SCM init, SCM split_to_date)
211
+ {
212
+ auto splits = xaccAccountGetSplits (acc);
213
+ auto less_scm = [](SCM a, SCM b) -> bool { return scm_is_true (scm_less_p (a, b)); };
214
+ auto get_date = [&](Split* s) -> SCM { return scm_call_1 (split_to_date, gnc_split_to_scm (s)); };
215
+ auto get_result = [&](Split* s) -> SCM { return scm_call_1 (split_fn, gnc_split_to_scm (s)); };
216
+ auto no_later_than_date = [&](auto s, SCM date) -> bool { return !less_scm (date, get_date (s)); };
217
+ std::sort (splits.begin (), splits.end (), [&](auto a, auto b) -> bool
218
+ { return less_scm (get_date (a), get_date (b)); });
219
+
220
+ return accumulate_splits_by_dates (splits, dates, init, no_later_than_date, get_result);
221
+ }
222
+
223
+
163
224
using AccountSet = std::unordered_set<Account*>;
164
225
static void maybe_add_descendants (Account* acc, AccountSet* accset)
165
226
{
0 commit comments