Converted the reconciler into an item_handler, so that it interacts

with the core the same way as everything else.
This commit is contained in:
John Wiegley 2005-02-15 11:04:48 +00:00
parent 7eafc0d9ca
commit 5ac4ab2fd5
2 changed files with 59 additions and 30 deletions

View file

@ -3,11 +3,11 @@
namespace ledger {
#define xact_next(x) ((transaction_t *)(x)->data)
#define xact_next_ptr(x) ((transaction_t **)&(x)->data)
#define xact_next(x) ((transaction_t *)transaction_xdata(*x).ptr)
#define xact_next_ptr(x) ((transaction_t **)&transaction_xdata(*x).ptr)
bool search_for_balance(amount_t& amount,
transaction_t ** prev, transaction_t * next)
static bool search_for_balance(amount_t& amount,
transaction_t ** prev, transaction_t * next)
{
for (; next; next = xact_next(next)) {
transaction_t * temp = *prev;
@ -24,21 +24,15 @@ bool search_for_balance(amount_t& amount,
return false;
}
static void push_chain_to_list(transaction_t * first,
transactions_list& xact_list)
void reconcile_transactions::push_to_handler(transaction_t * first)
{
while (first) {
transaction_t * curr = first;
xact_list.push_back(curr);
first = xact_next(first);
curr->data = 0;
}
for (; first; first = xact_next(first))
item_handler<transaction_t>::operator()(*first);
item_handler<transaction_t>::flush();
}
void reconcile_transactions(transactions_list& xact_list,
value_t& balance,
const time_t cutoff,
const bool all_pending)
void reconcile_transactions::flush()
{
value_t cleared_balance;
value_t pending_balance;
@ -46,11 +40,9 @@ void reconcile_transactions(transactions_list& xact_list,
transaction_t * first = NULL;
transaction_t ** last_ptr = &first;
clear_transactions_xdata();
bool found_pending = false;
for (transactions_list::iterator x = xact_list.begin();
x != xact_list.end();
for (transactions_list::iterator x = xacts.begin();
x != xacts.end();
x++)
if (! cutoff || std::difftime((*x)->entry->date, cutoff) < 0)
switch ((*x)->entry->state) {
@ -65,13 +57,12 @@ void reconcile_transactions(transactions_list& xact_list,
if (all_pending)
found_pending = true;
*last_ptr = *x;
last_ptr = (transaction_t **) &(*x)->data;
last_ptr = xact_next_ptr(*x);
break;
}
if (all_pending) {
xact_list.clear();
push_chain_to_list(first, xact_list);
push_to_handler(first);
return;
}
@ -95,11 +86,30 @@ void reconcile_transactions(transactions_list& xact_list,
pending_balance.cast(value_t::AMOUNT);
if (to_reconcile == *((amount_t *) pending_balance.data) ||
search_for_balance(to_reconcile, &first, first)) {
xact_list.clear();
push_chain_to_list(first, xact_list);
push_to_handler(first);
} else {
throw error("Could not reconcile account!");
}
}
} // namespace ledger
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
using namespace boost::python;
using namespace ledger;
void export_reconcile()
{
class_< reconcile_transactions, bases<item_handler<transaction_t> > >
("ReconcileTransactions",
init<item_handler<transaction_t> *, const value_t&, time_t, bool>()
[with_custodian_and_ward<1, 2>()])
.def("flush", &reconcile_transactions::flush)
.def("__call__", &reconcile_transactions::operator())
;
}
#endif // USE_BOOST_PYTHON

View file

@ -1,14 +1,33 @@
#ifndef _RECONCILE_H
#define _RECONCILE_H
#include "journal.h"
#include "value.h"
#include "walk.h"
namespace ledger {
void reconcile_transactions(transactions_list& xacts,
value_t& balance,
const time_t cutoff,
const bool all_pending = false);
class reconcile_transactions : public item_handler<transaction_t>
{
value_t balance;
time_t cutoff;
bool all_pending;
transactions_list xacts;
public:
reconcile_transactions(item_handler<transaction_t> * handler,
const value_t& _balance, const time_t _cutoff,
const bool _all_pending)
: item_handler<transaction_t>(handler),
balance(_balance), cutoff(_cutoff), all_pending(_all_pending) {}
void push_to_handler(transaction_t * first);
virtual void flush();
virtual void operator()(transaction_t& xact) {
xacts.push_back(&xact);
}
};
} // namespace ledger