234 lines
5.8 KiB
C++
234 lines
5.8 KiB
C++
#ifndef _WALK_H
|
|
#define _WALK_H
|
|
|
|
#include "ledger.h"
|
|
#include "balance.h"
|
|
#include "format.h"
|
|
#include "valexpr.h"
|
|
|
|
#include <iostream>
|
|
|
|
namespace ledger {
|
|
|
|
class item_predicate
|
|
{
|
|
const node_t * predicate;
|
|
balance_pair_t * balance;
|
|
unsigned int * index;
|
|
|
|
public:
|
|
item_predicate(const node_t * _predicate,
|
|
balance_pair_t * _balance = NULL,
|
|
unsigned int * _index = NULL)
|
|
: predicate(_predicate), balance(_balance), index(_index) {}
|
|
|
|
bool operator()(const entry_t * entry) const {
|
|
if (predicate) {
|
|
balance_t result;
|
|
predicate->compute(result, details_t(entry, balance, index));
|
|
return result;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool operator()(const transaction_t * xact) const {
|
|
if (predicate) {
|
|
balance_t result;
|
|
predicate->compute(result, details_t(xact, balance, index));
|
|
return result;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool operator()(const account_t * account) const {
|
|
if (predicate) {
|
|
balance_t result;
|
|
predicate->compute(result, details_t(account));
|
|
return result;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
inline void add_to_balance_pair(balance_pair_t& balance,
|
|
transaction_t * xact,
|
|
const bool inverted = false)
|
|
{
|
|
if (inverted) {
|
|
balance.quantity += - xact->amount;
|
|
balance.cost += - xact->cost;
|
|
} else {
|
|
balance += *xact;
|
|
}
|
|
}
|
|
|
|
class format_transaction
|
|
{
|
|
std::ostream& output_stream;
|
|
const format_t& first_line_format;
|
|
const format_t& next_lines_format;
|
|
mutable entry_t * last_entry;
|
|
|
|
public:
|
|
format_transaction(std::ostream& _output_stream,
|
|
const format_t& _first_line_format,
|
|
const format_t& _next_lines_format)
|
|
: output_stream(_output_stream),
|
|
first_line_format(_first_line_format),
|
|
next_lines_format(_next_lines_format),
|
|
last_entry(NULL) {}
|
|
|
|
void operator()(transaction_t * xact,
|
|
balance_pair_t * balance,
|
|
unsigned int * index,
|
|
const bool inverted) const;
|
|
};
|
|
|
|
class ignore_transaction
|
|
{
|
|
public:
|
|
void operator()(transaction_t * xact,
|
|
balance_pair_t * balance,
|
|
unsigned int * index,
|
|
const bool inverted) const {}
|
|
};
|
|
|
|
template <typename Function>
|
|
void handle_transaction(transaction_t * xact,
|
|
Function functor,
|
|
item_predicate& pred_functor,
|
|
const bool related,
|
|
const bool inverted,
|
|
balance_pair_t * balance = NULL,
|
|
unsigned int * index = NULL)
|
|
{
|
|
// If inverted is true, it implies related.
|
|
if (! inverted && ! (xact->flags & TRANSACTION_HANDLED)) {
|
|
xact->flags |= TRANSACTION_HANDLED;
|
|
if (pred_functor(xact)) {
|
|
xact->flags |= TRANSACTION_DISPLAYED;
|
|
functor(xact, balance, index, inverted);
|
|
}
|
|
}
|
|
|
|
if (related)
|
|
for (transactions_list::iterator i = xact->entry->transactions.begin();
|
|
i != xact->entry->transactions.end();
|
|
i++) {
|
|
if (*i == xact || ((*i)->flags & (TRANSACTION_AUTO |
|
|
TRANSACTION_HANDLED)))
|
|
continue;
|
|
|
|
(*i)->flags |= TRANSACTION_HANDLED;
|
|
if (pred_functor(xact)) {
|
|
xact->flags |= TRANSACTION_DISPLAYED;
|
|
functor(*i, balance, index, inverted);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename Function>
|
|
void walk_entries(entries_list::iterator begin,
|
|
entries_list::iterator end,
|
|
Function functor,
|
|
const node_t * predicate,
|
|
const bool related,
|
|
const bool inverted,
|
|
const node_t * display_predicate = NULL)
|
|
{
|
|
balance_pair_t balance;
|
|
unsigned int index;
|
|
item_predicate pred_functor(predicate, &balance, &index);
|
|
item_predicate disp_pred_functor(display_predicate, &balance, &index);
|
|
|
|
for (entries_list::iterator i = begin; i != end; i++)
|
|
for (transactions_list::iterator j = (*i)->transactions.begin();
|
|
j != (*i)->transactions.end();
|
|
j++)
|
|
if (pred_functor(*j))
|
|
handle_transaction(*j, functor, disp_pred_functor,
|
|
related, inverted, &balance, &index);
|
|
}
|
|
|
|
class format_account
|
|
{
|
|
std::ostream& output_stream;
|
|
const format_t& format;
|
|
|
|
mutable const account_t * last_account;
|
|
|
|
public:
|
|
format_account(std::ostream& _output_stream, const format_t& _format)
|
|
: output_stream(_output_stream), format(_format) {}
|
|
|
|
void operator()(const account_t * account, bool report_top = false);
|
|
};
|
|
|
|
void calc__accounts(account_t * account,
|
|
const node_t * predicate,
|
|
const bool related,
|
|
const bool inverted,
|
|
const bool calc_subtotals);
|
|
|
|
template <typename Function>
|
|
void walk__accounts(const account_t * account,
|
|
Function functor,
|
|
const node_t * display_predicate)
|
|
{
|
|
if (! display_predicate || item_predicate(display_predicate)(account))
|
|
functor(account);
|
|
|
|
for (accounts_map::const_iterator i = account->accounts.begin();
|
|
i != account->accounts.end();
|
|
i++)
|
|
walk__accounts((*i).second, functor, display_predicate);
|
|
}
|
|
|
|
template <typename Function>
|
|
void walk_accounts(account_t * account,
|
|
Function functor,
|
|
const node_t * predicate,
|
|
const bool related,
|
|
const bool inverted,
|
|
const bool calc_subtotals,
|
|
const node_t * display_predicate = NULL)
|
|
{
|
|
calc__accounts(account, predicate, related, inverted, calc_subtotals);
|
|
walk__accounts<Function>(account, functor, display_predicate);
|
|
}
|
|
|
|
#if 0
|
|
|
|
void sum_entries(entries_list& entries,
|
|
account_t * account,
|
|
const bool show_subtotals)
|
|
{
|
|
for (entries_list::const_iterator i = entries.begin();
|
|
i != entries.end();
|
|
i++)
|
|
for (transactions_list::const_iterator j = (*i)->transactions.begin();
|
|
j != (*i)->transactions.end();
|
|
j++)
|
|
if ((*j)->account == account) {
|
|
account->value += *(*j);
|
|
if (show_subtotals)
|
|
for (account_t * a = account;
|
|
a;
|
|
a = a->parent)
|
|
a->total += *(*j);
|
|
}
|
|
|
|
for (accounts_map::iterator i = account->accounts.begin();
|
|
i != account->accounts.end();
|
|
i++)
|
|
sum_items(entries, *i, show_subtotals);
|
|
}
|
|
|
|
#endif
|
|
|
|
} // namespace ledger
|
|
|
|
#endif // _WALK_H
|