summaryrefslogtreecommitdiff
path: root/item.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-07-26 23:33:51 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-07-26 23:33:51 -0400
commit161d6f79bd6f4ab45afa1cbae77548c8e508809a (patch)
tree55391f4997e20de173579d90b43316a968b27c9e /item.cc
parentfde56d0f1214b8fb9de5ba4d42d683ed494c45b0 (diff)
downloadfork-ledger-161d6f79bd6f4ab45afa1cbae77548c8e508809a.tar.gz
fork-ledger-161d6f79bd6f4ab45afa1cbae77548c8e508809a.tar.bz2
fork-ledger-161d6f79bd6f4ab45afa1cbae77548c8e508809a.zip
initial rev of 2.0
Diffstat (limited to 'item.cc')
-rw-r--r--item.cc224
1 files changed, 224 insertions, 0 deletions
diff --git a/item.cc b/item.cc
new file mode 100644
index 00000000..7e45ab07
--- /dev/null
+++ b/item.cc
@@ -0,0 +1,224 @@
+#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