improvements to transaction formatting
This commit is contained in:
parent
88df796880
commit
5db1e1165b
7 changed files with 232 additions and 127 deletions
|
|
@ -220,7 +220,7 @@ amount_t& amount_t::operator=(const double value)
|
||||||
amount_t& amount_t::operator+=(const amount_t& amt)
|
amount_t& amount_t::operator+=(const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (amt.quantity) {
|
if (amt.quantity) {
|
||||||
assert(commodity == amt.commodity);
|
assert(! commodity || commodity == amt.commodity);
|
||||||
INIT();
|
INIT();
|
||||||
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
|
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
122
format.cc
122
format.cc
|
|
@ -293,30 +293,130 @@ void format_t::format_elements(std::ostream& out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_transaction::operator()(transaction_t * xact)
|
void format_transaction::report_cumulative_subtotal() const
|
||||||
{
|
{
|
||||||
if (inverted) {
|
if (count == 1) {
|
||||||
xact->total.quantity += - xact->amount;
|
if (! intercept || ! intercept(last_xact))
|
||||||
xact->total.cost += - xact->cost;
|
first_line_format.format_elements(output_stream, details_t(last_xact));
|
||||||
} else {
|
return;
|
||||||
xact->total += *xact;
|
|
||||||
}
|
}
|
||||||
xact->index = index++;
|
|
||||||
|
assert(count > 1);
|
||||||
|
|
||||||
|
account_t splits(NULL, "<Total>");
|
||||||
|
transaction_t splits_total(NULL, &splits);
|
||||||
|
splits_total.total = subtotal;
|
||||||
|
|
||||||
|
balance_t value;
|
||||||
|
format_t::compute_total(value, details_t(&splits_total));
|
||||||
|
|
||||||
|
splits_total.entry = last_entry;
|
||||||
|
splits_total.total = last_xact->total;
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
for (amounts_map::const_iterator i = value.amounts.begin();
|
||||||
|
i != value.amounts.end();
|
||||||
|
i++) {
|
||||||
|
splits_total.amount = (*i).second;
|
||||||
|
splits_total.cost = (*i).second;
|
||||||
|
splits_total.total += (*i).second;
|
||||||
|
if (first) {
|
||||||
|
if (! intercept || ! intercept(&splits_total))
|
||||||
|
first_line_format.format_elements(output_stream,
|
||||||
|
details_t(&splits_total));
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
next_lines_format.format_elements(output_stream,
|
||||||
|
details_t(&splits_total));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void format_transaction::operator()(transaction_t * xact) const
|
||||||
|
{
|
||||||
|
if (last_xact)
|
||||||
|
xact->total = last_xact->total;
|
||||||
|
|
||||||
|
if (inverted) {
|
||||||
|
xact->amount.negate();
|
||||||
|
xact->cost.negate();
|
||||||
|
}
|
||||||
|
|
||||||
|
xact->total += *xact;
|
||||||
|
xact->index = last_xact ? last_xact->index + 1 : 0;
|
||||||
|
|
||||||
|
if (! disp_pred_functor(xact))
|
||||||
|
return;
|
||||||
|
|
||||||
|
xact->flags |= TRANSACTION_DISPLAYED;
|
||||||
|
|
||||||
// This makes the assumption that transactions from a single entry
|
// This makes the assumption that transactions from a single entry
|
||||||
// will always be grouped together.
|
// are always grouped together.
|
||||||
|
|
||||||
if (last_entry != xact->entry)
|
if (collapsed) {
|
||||||
|
// If we've reached a new entry, report on the subtotal
|
||||||
|
// accumulated thus far.
|
||||||
|
|
||||||
|
if (last_entry && last_entry != xact->entry) {
|
||||||
|
report_cumulative_subtotal();
|
||||||
|
subtotal = 0;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
subtotal += *xact;
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
if (last_entry != xact->entry) {
|
||||||
|
if (! intercept || ! intercept(xact))
|
||||||
first_line_format.format_elements(output_stream, details_t(xact));
|
first_line_format.format_elements(output_stream, details_t(xact));
|
||||||
else
|
} else {
|
||||||
next_lines_format.format_elements(output_stream, details_t(xact));
|
next_lines_format.format_elements(output_stream, details_t(xact));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverted) {
|
||||||
|
xact->amount.negate();
|
||||||
|
xact->cost.negate();
|
||||||
|
}
|
||||||
|
|
||||||
last_entry = xact->entry;
|
last_entry = xact->entry;
|
||||||
|
last_xact = xact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
bool report_changed_values(transaction_t * xact)
|
||||||
|
{
|
||||||
|
static transaction_t * last_xact = NULL;
|
||||||
|
|
||||||
|
if (last_xact) {
|
||||||
|
balance_t prev_bal, cur_bal;
|
||||||
|
format_t::compute_total(prev_bal, details_t(last_xact));
|
||||||
|
format_t::compute_total(cur_bal, details_t(xact));
|
||||||
|
|
||||||
|
if (balance_t diff = cur_bal - prev_bal) {
|
||||||
|
entry_t modified_entry;
|
||||||
|
transaction_t new_xact(&modified_entry, NULL);
|
||||||
|
|
||||||
|
modified_entry.date = xact ? xact->entry->date : std::time(NULL);
|
||||||
|
modified_entry.payee = "Commodities revalued";
|
||||||
|
|
||||||
|
new_xact.amount = diff.amount();
|
||||||
|
format_t::compute_value(diff, details_t(xact));
|
||||||
|
new_xact.total = cur_bal - diff;
|
||||||
|
|
||||||
|
functor(&new_xact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_xact = xact;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void format_account::operator()(const account_t * account,
|
void format_account::operator()(const account_t * account,
|
||||||
const unsigned int max_depth,
|
const unsigned int max_depth,
|
||||||
const bool report_top)
|
const bool report_top) const
|
||||||
{
|
{
|
||||||
// Don't output the account if only one child will be displayed
|
// Don't output the account if only one child will be displayed
|
||||||
// which shows the exact same amount. jww (2004-08-03): How do
|
// which shows the exact same amount. jww (2004-08-03): How do
|
||||||
|
|
|
||||||
54
format.h
54
format.h
|
|
@ -87,36 +87,72 @@ class format_transaction
|
||||||
std::ostream& output_stream;
|
std::ostream& output_stream;
|
||||||
const format_t& first_line_format;
|
const format_t& first_line_format;
|
||||||
const format_t& next_lines_format;
|
const format_t& next_lines_format;
|
||||||
|
const bool collapsed;
|
||||||
const bool inverted;
|
const bool inverted;
|
||||||
unsigned int index;
|
|
||||||
entry_t * last_entry;
|
item_predicate<transaction_t> disp_pred_functor;
|
||||||
|
|
||||||
|
typedef bool (*intercept_t)(transaction_t * xact);
|
||||||
|
|
||||||
|
intercept_t intercept;
|
||||||
|
|
||||||
|
mutable balance_pair_t subtotal;
|
||||||
|
mutable unsigned int count;
|
||||||
|
mutable entry_t * last_entry;
|
||||||
|
mutable transaction_t * last_xact;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_transaction(std::ostream& _output_stream,
|
format_transaction(std::ostream& _output_stream,
|
||||||
const format_t& _first_line_format,
|
const format_t& _first_line_format,
|
||||||
const format_t& _next_lines_format,
|
const format_t& _next_lines_format,
|
||||||
const bool _inverted)
|
const node_t * display_predicate,
|
||||||
|
const bool _collapsed = false,
|
||||||
|
const bool _inverted = false,
|
||||||
|
intercept_t _intercept = NULL)
|
||||||
: output_stream(_output_stream),
|
: output_stream(_output_stream),
|
||||||
first_line_format(_first_line_format),
|
first_line_format(_first_line_format),
|
||||||
next_lines_format(_next_lines_format),
|
next_lines_format(_next_lines_format),
|
||||||
inverted(_inverted), index(0), last_entry(NULL) {}
|
collapsed(_collapsed), inverted(_inverted),
|
||||||
|
disp_pred_functor(display_predicate),
|
||||||
|
intercept(_intercept), count(0),
|
||||||
|
last_entry(NULL), last_xact(NULL) {}
|
||||||
|
|
||||||
void operator()(transaction_t * xact);
|
void start() const {}
|
||||||
|
void finish() const {
|
||||||
|
if (subtotal)
|
||||||
|
report_cumulative_subtotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void report_cumulative_subtotal() const;
|
||||||
|
void operator()(transaction_t * xact) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// An intercept that can be used to report changes in commodity value
|
||||||
|
bool report_changed_values(transaction_t * xact);
|
||||||
|
|
||||||
|
|
||||||
class format_account
|
class format_account
|
||||||
{
|
{
|
||||||
std::ostream& output_stream;
|
std::ostream& output_stream;
|
||||||
const format_t& format;
|
const format_t& format;
|
||||||
const account_t * last_account;
|
|
||||||
|
item_predicate<account_t> disp_pred_functor;
|
||||||
|
|
||||||
|
mutable const account_t * last_account;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_account(std::ostream& _output_stream, const format_t& _format)
|
format_account(std::ostream& _output_stream,
|
||||||
: output_stream(_output_stream), format(_format) {}
|
const format_t& _format,
|
||||||
|
const node_t * display_predicate = NULL)
|
||||||
|
: output_stream(_output_stream), format(_format),
|
||||||
|
disp_pred_functor(display_predicate), last_account(NULL) {}
|
||||||
|
|
||||||
|
void start() const {}
|
||||||
|
void finish() const {}
|
||||||
|
|
||||||
void operator()(const account_t * account,
|
void operator()(const account_t * account,
|
||||||
const unsigned int max_depth = 1,
|
const unsigned int max_depth = 1,
|
||||||
const bool report_top = false);
|
const bool report_top = false) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
7
ledger.h
7
ledger.h
|
|
@ -28,6 +28,8 @@ namespace ledger {
|
||||||
#define TRANSACTION_HANDLED 0x08
|
#define TRANSACTION_HANDLED 0x08
|
||||||
#define TRANSACTION_DISPLAYED 0x10
|
#define TRANSACTION_DISPLAYED 0x10
|
||||||
|
|
||||||
|
#define TRANSACTION_TRANSIENT (TRANSACTION_HANDLED | TRANSACTION_DISPLAYED)
|
||||||
|
|
||||||
class entry_t;
|
class entry_t;
|
||||||
class account_t;
|
class account_t;
|
||||||
|
|
||||||
|
|
@ -44,7 +46,8 @@ class transaction_t
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
||||||
transaction_t(entry_t * _entry, account_t * _account)
|
transaction_t(entry_t * _entry, account_t * _account)
|
||||||
: entry(_entry), account(_account), flags(TRANSACTION_NORMAL) {}
|
: entry(_entry), account(_account), flags(TRANSACTION_NORMAL),
|
||||||
|
index(0) {}
|
||||||
|
|
||||||
transaction_t(entry_t * _entry,
|
transaction_t(entry_t * _entry,
|
||||||
account_t * _account,
|
account_t * _account,
|
||||||
|
|
@ -53,7 +56,7 @@ class transaction_t
|
||||||
unsigned int _flags = TRANSACTION_NORMAL,
|
unsigned int _flags = TRANSACTION_NORMAL,
|
||||||
const std::string& _note = "")
|
const std::string& _note = "")
|
||||||
: entry(_entry), account(_account), amount(_amount),
|
: entry(_entry), account(_account), amount(_amount),
|
||||||
cost(_cost), flags(_flags), note(_note) {}
|
cost(_cost), flags(_flags), note(_note), index(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
56
main.cc
56
main.cc
|
|
@ -31,9 +31,6 @@ static const std::string reg_fmt
|
||||||
static const std::string print_fmt
|
static const std::string print_fmt
|
||||||
= "\n%10d %X%C%p\n %-34N %12o\n%/ %-34N %12o\n";
|
= "\n%10d %X%C%p\n %-34N %12o\n%/ %-34N %12o\n";
|
||||||
|
|
||||||
static bool show_commodities_revalued = false;
|
|
||||||
static bool show_commodities_revalued_only = false;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
static void report_value_change(std::ostream& out,
|
static void report_value_change(std::ostream& out,
|
||||||
|
|
@ -44,33 +41,6 @@ static void report_value_change(std::ostream& out,
|
||||||
const format_t& first_line_format,
|
const format_t& first_line_format,
|
||||||
const format_t& next_lines_format)
|
const format_t& next_lines_format)
|
||||||
{
|
{
|
||||||
static std::time_t prev_date = -1;
|
|
||||||
if (prev_date == -1) {
|
|
||||||
prev_date = date;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
item_t temp;
|
|
||||||
temp.date = prev_date;
|
|
||||||
temp.total = prev_balance;
|
|
||||||
balance_t prev_bal = format_t::compute_total(&temp);
|
|
||||||
|
|
||||||
temp.date = date;
|
|
||||||
temp.total = balance;
|
|
||||||
balance_t cur_bal = format_t::compute_total(&temp);
|
|
||||||
|
|
||||||
if (balance_t diff = cur_bal - prev_bal) {
|
|
||||||
temp.value = diff;
|
|
||||||
temp.total = balance;
|
|
||||||
temp.payee = "Commodities revalued";
|
|
||||||
|
|
||||||
if (value_predicate(predicate)(&temp)) {
|
|
||||||
first_line_format.format_elements(out, &temp);
|
|
||||||
next_lines_format.format_elements(out, &temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_date = date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_report(std::ostream& out,
|
void register_report(std::ostream& out,
|
||||||
|
|
@ -307,6 +277,9 @@ int main(int argc, char * argv[])
|
||||||
bool show_inverted = false;
|
bool show_inverted = false;
|
||||||
bool show_empty = false;
|
bool show_empty = false;
|
||||||
|
|
||||||
|
bool show_commodities_revalued = false;
|
||||||
|
bool show_commodities_revalued_only = false;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -763,16 +736,19 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
if (command == "b") {
|
if (command == "b") {
|
||||||
format_t format(f);
|
format_t format(f);
|
||||||
walk_accounts(journal->master, format_account(std::cout, format),
|
format_account formatter(std::cout, format, display_predicate.get());
|
||||||
predicate.get(), xact_display_flags, show_subtotals,
|
formatter.start();
|
||||||
show_expanded ? 0 : 1, display_predicate.get(),
|
walk_accounts(journal->master, formatter, predicate.get(),
|
||||||
|
xact_display_flags, show_subtotals, show_expanded ? 0 : 1,
|
||||||
sort_order.get());
|
sort_order.get());
|
||||||
|
formatter.finish();
|
||||||
|
|
||||||
if (! display_predicate.get() ||
|
if (! display_predicate.get() ||
|
||||||
item_predicate<account_t>(display_predicate.get())(journal->master)) {
|
item_predicate<account_t>(display_predicate.get())(journal->master)) {
|
||||||
std::string end_format = "--------------------\n";
|
std::string end_format = "--------------------\n";
|
||||||
format.reset(end_format + f);
|
format.reset(end_format + f);
|
||||||
format_account(std::cout, format)(journal->master, true);
|
format_account(std::cout, format)(journal->master, true,
|
||||||
|
display_predicate.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::string first_line_format;
|
std::string first_line_format;
|
||||||
|
|
@ -787,22 +763,26 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
format_t format(first_line_format);
|
format_t format(first_line_format);
|
||||||
format_t nformat(next_lines_format);
|
format_t nformat(next_lines_format);
|
||||||
format_transaction formatter(std::cout, format, nformat, show_inverted);
|
|
||||||
|
format_transaction formatter(std::cout, format, nformat,
|
||||||
|
display_predicate.get(),
|
||||||
|
! show_subtotals, show_inverted);
|
||||||
|
formatter.start();
|
||||||
|
|
||||||
if (! sort_order.get()) {
|
if (! sort_order.get()) {
|
||||||
walk_entries(journal->entries.begin(), journal->entries.end(),
|
walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||||
formatter, predicate.get(), xact_display_flags,
|
formatter, predicate.get(), xact_display_flags);
|
||||||
display_predicate.get());
|
|
||||||
} else {
|
} else {
|
||||||
transactions_deque transactions_pool;
|
transactions_deque transactions_pool;
|
||||||
walk_entries(journal->entries.begin(), journal->entries.end(),
|
walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||||
collect_transactions(transactions_pool), predicate.get(),
|
collect_transactions(transactions_pool), predicate.get(),
|
||||||
xact_display_flags, display_predicate.get());
|
xact_display_flags);
|
||||||
std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
|
std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
|
||||||
compare_items<transaction_t>(sort_order.get()));
|
compare_items<transaction_t>(sort_order.get()));
|
||||||
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
|
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
|
||||||
formatter);
|
formatter);
|
||||||
}
|
}
|
||||||
|
formatter.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the cache, if need be
|
// Save the cache, if need be
|
||||||
|
|
|
||||||
19
valexpr.h
19
valexpr.h
|
|
@ -136,6 +136,25 @@ inline node_t * find_node(node_t * node, node_t::kind_t type) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class item_predicate
|
||||||
|
{
|
||||||
|
const node_t * predicate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
item_predicate(const node_t * _predicate) : predicate(_predicate) {}
|
||||||
|
|
||||||
|
bool operator()(const T * item) const {
|
||||||
|
if (predicate) {
|
||||||
|
balance_t result;
|
||||||
|
predicate->compute(result, details_t(item));
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace report
|
} // namespace report
|
||||||
|
|
||||||
#endif // _REPORT_H
|
#endif // _REPORT_H
|
||||||
|
|
|
||||||
77
walk.h
77
walk.h
|
|
@ -10,25 +10,6 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class item_predicate
|
|
||||||
{
|
|
||||||
const node_t * predicate;
|
|
||||||
|
|
||||||
public:
|
|
||||||
item_predicate(const node_t * _predicate) : predicate(_predicate) {}
|
|
||||||
|
|
||||||
bool operator()(const T * item) const {
|
|
||||||
if (predicate) {
|
|
||||||
balance_t result;
|
|
||||||
predicate->compute(result, details_t(item));
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct compare_items {
|
struct compare_items {
|
||||||
const node_t * sort_order;
|
const node_t * sort_order;
|
||||||
|
|
@ -59,7 +40,7 @@ class collect_transactions
|
||||||
collect_transactions(transactions_deque& _transactions)
|
collect_transactions(transactions_deque& _transactions)
|
||||||
: transactions(_transactions) {}
|
: transactions(_transactions) {}
|
||||||
|
|
||||||
void operator()(transaction_t * xact) {
|
void operator()(transaction_t * xact) const {
|
||||||
transactions.push_back(xact);
|
transactions.push_back(xact);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -81,18 +62,15 @@ class ignore_transaction
|
||||||
#define OTHER_TRANSACTIONS 0x02
|
#define OTHER_TRANSACTIONS 0x02
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void handle_transaction(transaction_t * xact, Function functor,
|
void handle_transaction(transaction_t * xact,
|
||||||
item_predicate<transaction_t>& pred_functor,
|
const Function& functor,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
if ((flags & MATCHING_TRANSACTIONS) &&
|
if ((flags & MATCHING_TRANSACTIONS) &&
|
||||||
! (xact->flags & TRANSACTION_HANDLED)) {
|
! (xact->flags & TRANSACTION_HANDLED)) {
|
||||||
xact->flags |= TRANSACTION_HANDLED;
|
xact->flags |= TRANSACTION_HANDLED;
|
||||||
if (pred_functor(xact)) {
|
|
||||||
xact->flags |= TRANSACTION_DISPLAYED;
|
|
||||||
functor(xact);
|
functor(xact);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & OTHER_TRANSACTIONS)
|
if (flags & OTHER_TRANSACTIONS)
|
||||||
for (transactions_list::iterator i = xact->entry->transactions.begin();
|
for (transactions_list::iterator i = xact->entry->transactions.begin();
|
||||||
|
|
@ -103,35 +81,30 @@ void handle_transaction(transaction_t * xact, Function functor,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
(*i)->flags |= TRANSACTION_HANDLED;
|
(*i)->flags |= TRANSACTION_HANDLED;
|
||||||
if (pred_functor(xact)) {
|
|
||||||
xact->flags |= TRANSACTION_DISPLAYED;
|
|
||||||
functor(*i);
|
functor(*i);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk_entries(entries_list::iterator begin,
|
void walk_entries(entries_list::iterator begin,
|
||||||
entries_list::iterator end,
|
entries_list::iterator end,
|
||||||
Function functor,
|
const Function& functor,
|
||||||
const node_t * predicate,
|
const node_t * predicate,
|
||||||
unsigned int flags,
|
unsigned int flags)
|
||||||
const node_t * display_predicate = NULL)
|
|
||||||
{
|
{
|
||||||
item_predicate<transaction_t> pred_functor(predicate);
|
item_predicate<transaction_t> pred_functor(predicate);
|
||||||
item_predicate<transaction_t> disp_pred_functor(display_predicate);
|
|
||||||
|
|
||||||
for (entries_list::iterator i = begin; i != end; i++)
|
for (entries_list::iterator i = begin; i != end; i++)
|
||||||
for (transactions_list::iterator j = (*i)->transactions.begin();
|
for (transactions_list::iterator j = (*i)->transactions.begin();
|
||||||
j != (*i)->transactions.end();
|
j != (*i)->transactions.end();
|
||||||
j++)
|
j++)
|
||||||
if (pred_functor(*j))
|
if (pred_functor(*j))
|
||||||
handle_transaction(*j, functor, disp_pred_functor, flags);
|
handle_transaction(*j, functor, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk_entries(entries_list::iterator begin,
|
void walk_entries(entries_list::iterator begin,
|
||||||
entries_list::iterator end, Function functor)
|
entries_list::iterator end, const Function& functor)
|
||||||
{
|
{
|
||||||
for (entries_list::iterator i = begin; i != end; i++)
|
for (entries_list::iterator i = begin; i != end; i++)
|
||||||
for (transactions_list::iterator j = (*i)->transactions.begin();
|
for (transactions_list::iterator j = (*i)->transactions.begin();
|
||||||
|
|
@ -144,7 +117,7 @@ class clear_flags
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void operator()(transaction_t * xact) const {
|
void operator()(transaction_t * xact) const {
|
||||||
xact->flags &= ~(TRANSACTION_HANDLED | TRANSACTION_DISPLAYED);
|
xact->flags &= ~TRANSACTION_TRANSIENT;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -156,7 +129,8 @@ inline void clear_transaction_display_flags(entries_list::iterator begin,
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk_transactions(transactions_list::iterator begin,
|
void walk_transactions(transactions_list::iterator begin,
|
||||||
transactions_list::iterator end, Function functor)
|
transactions_list::iterator end,
|
||||||
|
const Function& functor)
|
||||||
{
|
{
|
||||||
for (transactions_list::iterator i = begin; i != end; i++)
|
for (transactions_list::iterator i = begin; i != end; i++)
|
||||||
functor(*i);
|
functor(*i);
|
||||||
|
|
@ -164,7 +138,8 @@ void walk_transactions(transactions_list::iterator begin,
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk_transactions(transactions_deque::iterator begin,
|
void walk_transactions(transactions_deque::iterator begin,
|
||||||
transactions_deque::iterator end, Function functor)
|
transactions_deque::iterator end,
|
||||||
|
const Function& functor)
|
||||||
{
|
{
|
||||||
for (transactions_deque::iterator i = begin; i != end; i++)
|
for (transactions_deque::iterator i = begin; i != end; i++)
|
||||||
functor(*i);
|
functor(*i);
|
||||||
|
|
@ -187,27 +162,23 @@ inline void sort_accounts(account_t * account,
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk__accounts(const account_t * account,
|
void walk__accounts(const account_t * account,
|
||||||
Function functor,
|
const Function& functor,
|
||||||
const unsigned int max_depth,
|
const unsigned int max_depth)
|
||||||
item_predicate<account_t>& disp_pred_functor)
|
|
||||||
{
|
{
|
||||||
if (disp_pred_functor(account))
|
|
||||||
functor(account, max_depth);
|
functor(account, max_depth);
|
||||||
|
|
||||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||||
i != account->accounts.end();
|
i != account->accounts.end();
|
||||||
i++)
|
i++)
|
||||||
walk__accounts((*i).second, functor, max_depth, disp_pred_functor);
|
walk__accounts((*i).second, functor, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk__accounts_sorted(const account_t * account,
|
void walk__accounts_sorted(const account_t * account,
|
||||||
Function functor,
|
const Function& functor,
|
||||||
const unsigned int max_depth,
|
const unsigned int max_depth,
|
||||||
const node_t * sort_order,
|
const node_t * sort_order)
|
||||||
item_predicate<account_t>& disp_pred_functor)
|
|
||||||
{
|
{
|
||||||
if (disp_pred_functor(account))
|
|
||||||
functor(account, max_depth);
|
functor(account, max_depth);
|
||||||
|
|
||||||
accounts_deque accounts;
|
accounts_deque accounts;
|
||||||
|
|
@ -223,12 +194,11 @@ void walk__accounts_sorted(const account_t * account,
|
||||||
for (accounts_deque::const_iterator i = accounts.begin();
|
for (accounts_deque::const_iterator i = accounts.begin();
|
||||||
i != accounts.end();
|
i != accounts.end();
|
||||||
i++)
|
i++)
|
||||||
walk__accounts_sorted(*i, functor, max_depth, sort_order,
|
walk__accounts_sorted(*i, functor, max_depth, sort_order);
|
||||||
disp_pred_functor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void for_each_account(account_t * account, Function functor)
|
void for_each_account(account_t * account, const Function& functor)
|
||||||
{
|
{
|
||||||
functor(account);
|
functor(account);
|
||||||
|
|
||||||
|
|
@ -255,26 +225,23 @@ inline void sum__accounts(account_t * account)
|
||||||
|
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
void walk_accounts(account_t * account,
|
void walk_accounts(account_t * account,
|
||||||
Function functor,
|
const Function& functor,
|
||||||
const node_t * predicate,
|
const node_t * predicate,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
const bool calc_subtotals,
|
const bool calc_subtotals,
|
||||||
const unsigned int max_depth,
|
const unsigned int max_depth,
|
||||||
const node_t * display_predicate = NULL,
|
|
||||||
const node_t * sort_order = NULL)
|
const node_t * sort_order = NULL)
|
||||||
{
|
{
|
||||||
item_predicate<transaction_t> pred_functor(predicate);
|
item_predicate<transaction_t> pred_functor(predicate);
|
||||||
item_predicate<account_t> disp_pred_functor(display_predicate);
|
|
||||||
|
|
||||||
calc__accounts(account, pred_functor, flags);
|
calc__accounts(account, pred_functor, flags);
|
||||||
if (calc_subtotals)
|
if (calc_subtotals)
|
||||||
sum__accounts(account);
|
sum__accounts(account);
|
||||||
|
|
||||||
if (sort_order)
|
if (sort_order)
|
||||||
walk__accounts_sorted<Function>(account, functor, max_depth, sort_order,
|
walk__accounts_sorted<Function>(account, functor, max_depth, sort_order);
|
||||||
disp_pred_functor);
|
|
||||||
else
|
else
|
||||||
walk__accounts<Function>(account, functor, max_depth, disp_pred_functor);
|
walk__accounts<Function>(account, functor, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue