@@ -66,6 +66,9 @@ 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
+ SCM gnc_account_accumulate_at_dates (const Account *acc, SCM dates, SCM last_result,
70
+ SCM split_to_date, SCM split_to_elt);
71
+
69
72
AccountVec gnc_accounts_and_all_descendants (AccountVec accounts);
70
73
71
74
extern " C"
@@ -160,6 +163,58 @@ SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date
160
163
return rv;
161
164
}
162
165
166
+ SCM
167
+ gnc_account_accumulate_at_dates (const Account *acc, SCM dates, SCM last_result,
168
+ SCM split_to_date, SCM split_to_elt)
169
+ {
170
+ std::function<SCM (Split*)> get_date;
171
+ if (scm_is_false (split_to_date))
172
+ get_date = [&](auto s){ return scm_from_int64 (xaccTransGetDate (xaccSplitGetParent (s))); };
173
+ else
174
+ get_date = [&](auto s){ return scm_call_1 (split_to_date, gnc_split_to_scm (s)); };
175
+
176
+ // because the guile < function understands +inf.0
177
+ auto less_scm = [&](SCM a, SCM b){ return scm_is_true (scm_less_p (a, b)); };
178
+
179
+ // make a copy of splits vector
180
+ auto splits{xaccAccountGetSplits (acc)};
181
+ if (!scm_is_false (split_to_date))
182
+ std::sort (splits.begin (), splits.end (),
183
+ [&](auto a, auto b){ return less_scm (get_date (a), get_date (b)); });
184
+
185
+ SCM rv = SCM_EOL;
186
+ for (auto splits_it = splits.begin (); !scm_is_null (dates); )
187
+ {
188
+ auto after_date = [&](auto s){ return less_scm (scm_car (dates), get_date (s)); };
189
+ auto get_result = [&]() { return scm_call_1 (split_to_elt, gnc_split_to_scm (*splits_it)); };
190
+ if (splits_it == splits.end ())
191
+ {
192
+ rv = scm_cons (last_result, rv);
193
+ dates = scm_cdr (dates);
194
+ }
195
+ else if (auto nx_it = std::next (splits_it); nx_it != splits.end () && !after_date (*nx_it))
196
+ {
197
+ last_result = get_result ();
198
+ splits_it++;
199
+ }
200
+ else if (after_date (*splits_it))
201
+ {
202
+ rv = scm_cons (last_result, rv);
203
+ dates = scm_cdr (dates);
204
+ }
205
+ else
206
+ {
207
+ last_result = get_result ();
208
+ rv = scm_cons (last_result, rv);
209
+ dates = scm_cdr (dates);
210
+ splits_it++;
211
+ }
212
+ }
213
+
214
+ return scm_reverse (rv);
215
+ }
216
+
217
+
163
218
using AccountSet = std::unordered_set<Account*>;
164
219
static void maybe_add_descendants (Account* acc, AccountSet* accset)
165
220
{
0 commit comments