blob: 894175c2c8a967ebb523920c2682ee8550a4898d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
#include "reconcile.h"
namespace ledger {
reconcile_results_t reconcile_account(journal_t& journal,
account_t& account,
const value_t& balance)
{
// This routine attempts to reconcile an account against a given
// `balance' by marking transactions as "cleared" until the cleared
// balance matches the expected `balance'.
//
// The real difficulty is that sometimes there are transactions in
// the journal which never make it to the statement (they might be
// drawing from the wrong account), or there could be transactions
// which haven't been added yet. In both of these cases the best
// one can do is guess, and if that fails, to throw up their hands
// in despair.
//
// As such, this algorithm is very likely to fail. The hope is that
// sometimes it won't fail, and then it can save the user a fair bit
// of time.
//
// If the algorithm succeeds in auto-reconciling the account, then
// all the relevant data is return in the form of a
// `reconcile_results_t' structure (see reconcile.h).
// Compute the current balances for the given account.
value_t cleared_balance;
value_t pending_balance;
reconcile_results_t results;
transactions_list pending_xacts;
for (entries_list::iterator e = journal.entries.begin();
e != journal.entries.end();
e++)
for (transactions_list::iterator x = (*e)->transactions.begin();
x != (*e)->transactions.end();
x++)
if ((*x)->account == &account) {
switch ((*e)->state) {
case entry_t::CLEARED:
cleared_balance += (*x)->amount;
break;
case entry_t::UNCLEARED:
case entry_t::PENDING:
pending_balance += (*x)->amount;
pending_xacts.push_back(*x);
break;
}
}
results.previous_balance = cleared_balance;
value_t to_reconcile = balance - cleared_balance;
// If the amount to reconcile is the same as the pending balance,
// then assume an exact match and return the results right away.
if (to_reconcile == pending_balance) {
results.remaining_balance = 0L;
results.pending_xacts = pending_xacts;
return results;
}
throw error("Could not reconcile account");
}
} // namespace ledger
|