Added framework for an auto-reconcile command. Useful primarily for
GUI developers.
This commit is contained in:
parent
37a67d89b0
commit
23f8faad13
3 changed files with 94 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ libledger_a_SOURCES = \
|
|||
parser.cc \
|
||||
qif.cc \
|
||||
quotes.cc \
|
||||
reconcile.cc \
|
||||
textual.cc \
|
||||
valexpr.cc \
|
||||
value.cc \
|
||||
|
|
@ -52,6 +53,7 @@ pkginclude_HEADERS = \
|
|||
pyledger.h \
|
||||
qif.h \
|
||||
quotes.h \
|
||||
reconcile.h \
|
||||
textual.h \
|
||||
timing.h \
|
||||
util.h \
|
||||
|
|
|
|||
69
reconcile.cc
Normal file
69
reconcile.cc
Normal file
|
|
@ -0,0 +1,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
|
||||
23
reconcile.h
Normal file
23
reconcile.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _RECONCILE_H
|
||||
#define _RECONCILE_H
|
||||
|
||||
#include "journal.h"
|
||||
#include "walk.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
struct reconcile_results_t
|
||||
{
|
||||
value_t previous_balance;
|
||||
value_t remaining_balance;
|
||||
|
||||
transactions_list pending_xacts;
|
||||
};
|
||||
|
||||
reconcile_results_t reconcile_account(journal_t& journal,
|
||||
account_t& account,
|
||||
const value_t& balance);
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _RECONCILE_H
|
||||
Loading…
Add table
Reference in a new issue