ledger/item.cc
2004-07-26 23:33:51 -04:00

224 lines
5.4 KiB
C++

#include "item.h"
namespace ledger {
// jww (2004-07-21): If format.show_empty is set, then include all
// subaccounts, empty balanced or no
item_t * walk_accounts(const account_t * account,
const constraints_t& constraints,
const bool compute_subtotals)
{
item_t * item = new item_t;
item->account = account;
item->date = end_date(constraints);
for (constrained_transactions_list_const_iterator
i(account->transactions.begin(),
account->transactions.end(), constraints);
i != account->transactions.end();
i++) {
item->value += *(*i);
if (compute_subtotals)
item->total += *(*i);
}
for (accounts_map::const_iterator i = account->accounts.begin();
i != account->accounts.end();
i++) {
item_t * subitem = walk_accounts((*i).second, constraints,
compute_subtotals);
subitem->parent = item;
if (compute_subtotals)
item->total += subitem->total;
if (compute_subtotals ? subitem->total : subitem->value)
item->subitems.push_back(subitem);
}
return item;
}
static inline void sum_items(const item_t * top,
item_t * item,
const bool compute_subtotals)
{
if (top->account == item->account) {
item->value += top->value;
if (compute_subtotals)
item->total += top->value;
}
for (items_deque::const_iterator i = top->subitems.begin();
i != top->subitems.end();
i++)
sum_items(*i, item, compute_subtotals);
}
item_t * walk_items(const item_t * top,
const account_t * account,
const constraints_t& constraints,
const bool compute_subtotals)
{
item_t * item = new item_t;
item->account = account;
sum_items(top, item, compute_subtotals);
for (accounts_map::const_iterator i = account->accounts.begin();
i != account->accounts.end();
i++) {
item_t * subitem = walk_items(top, (*i).second, constraints,
compute_subtotals);
subitem->parent = item;
if (compute_subtotals)
item->total += subitem->total;
if (compute_subtotals ? subitem->total : subitem->value)
item->subitems.push_back(subitem);
}
return item;
}
item_t * walk_entries(entries_list::const_iterator begin,
entries_list::const_iterator end,
const constraints_t& constraints,
const format_t& format)
{
#if 0
int last_mon = -1;
#endif
unsigned int count = 0;
item_t * result = NULL;
for (constrained_entries_list_const_iterator i(begin, end, constraints);
i != end;
i++) {
item_t * item = NULL;
for (constrained_transactions_list_const_iterator
j((*i)->transactions.begin(), (*i)->transactions.end(),
constraints);
j != (*i)->transactions.end();
j++) {
assert(*i == (*j)->entry);
if (! item) {
item = new item_t;
item->index = count++;
item->date = (*i)->date;
item->payee = (*i)->payee;
}
if (! format.show_inverted) {
item_t * subitem = new item_t;
subitem->parent = item;
subitem->date = item->date;
subitem->account = (*j)->account;
subitem->value = *(*j);
item->subitems.push_back(subitem);
}
if (format.show_related)
for (transactions_list::iterator k = (*i)->transactions.begin();
k != (*i)->transactions.end();
k++)
if (*k != *j && ! ((*k)->flags & TRANSACTION_VIRTUAL)) {
item_t * subitem = new item_t;
subitem->parent = item;
subitem->date = item->date;
subitem->account = (*k)->account;
subitem->value = *(*k);
if (format.show_inverted)
subitem->value.negate();
item->subitems.push_back(subitem);
}
#if 0
// If we are collecting monthly totals, then add them if the
// month of this entry is different from the month of previous
// entries.
if (format.period == PERIOD_MONTHLY) {
int entry_mon = std::gmtime(&(*i)->date)->tm_mon;
if (last_mon != -1 && entry_mon != last_mon &&
line_balances.size() > 0) {
if (last_date == 0)
last_date = (*i)->date;
if (reg) {
char buf[32];
std::strftime(buf, 31, "%B", std::gmtime(&last_date));
reg->lines.push_back(register_line_t(last_date, buf));
reg->lines.back().compute_items(line_balances, total, count);
} else {
count++;
}
line_balances.clear();
}
last_mon = entry_mon;
last_date = (*i)->date;
}
#endif
}
if (item) {
if (! result)
result = new item_t;
item->parent = result;
result->subitems.push_back(item);
}
}
return result;
#if 0
// Wrap up any left over balance list information.
if (line_balances.size() > 0) {
assert(format.period == PERIOD_MONTHLY);
assert(last_date != 0);
if (reg) {
char buf[32];
std::strftime(buf, 31, "%B", std::gmtime(&last_date));
reg->lines.push_back(register_line_t(last_date, buf));
reg->lines.back().compute_items(line_balances, total, count);
} else {
count++;
}
//line_balances.clear();
}
return count;
#endif
}
struct cmp_items {
const node_t * sort_order;
cmp_items(const node_t * _sort_order) : sort_order(_sort_order) {}
bool operator()(const item_t * left, const item_t * right) const {
assert(left);
assert(right);
assert(sort_order);
return sort_order->compute(left) < sort_order->compute(right);
}
};
void item_t::sort(const node_t * sort_order)
{
std::sort(subitems.begin(), subitems.end(), cmp_items(sort_order));
}
} // namespace ledger