summaryrefslogtreecommitdiff
path: root/walk.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-08-11 01:37:12 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-08-11 01:37:12 -0400
commit3edf2986335280bb13fffc51f23212622a79c9a9 (patch)
treebf9171e0c3d3514e76470fffb96042dea9d973e4 /walk.cc
parentec73e300e87b1dd7bb174d7ebb426ae4a8e97c8e (diff)
downloadfork-ledger-3edf2986335280bb13fffc51f23212622a79c9a9.tar.gz
fork-ledger-3edf2986335280bb13fffc51f23212622a79c9a9.tar.bz2
fork-ledger-3edf2986335280bb13fffc51f23212622a79c9a9.zip
added several kinds of transaction filters
Diffstat (limited to 'walk.cc')
-rw-r--r--walk.cc146
1 files changed, 144 insertions, 2 deletions
diff --git a/walk.cc b/walk.cc
index ee915164..bbc56604 100644
--- a/walk.cc
+++ b/walk.cc
@@ -1,9 +1,151 @@
#include "walk.h"
+#include "format.h"
namespace ledger {
-struct sum_in_account : public item_handler<transaction_t> {
- virtual void operator()(transaction_t * xact) const {
+void calc_transactions::operator()(transaction_t * xact)
+{
+ 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;
+
+ (*handler)(xact);
+
+ if (inverted) {
+ xact->amount.negate();
+ xact->cost.negate();
+ }
+
+ last_xact = xact;
+}
+
+void collapse_transactions::report_cumulative_subtotal()
+{
+ if (count == 1) {
+ (*handler)(last_xact);
+ return;
+ }
+
+ assert(count > 1);
+
+ transaction_t * total_xact = new transaction_t(NULL, totals_account);
+
+ balance_t value;
+ total_xact->total = subtotal;
+ format_t::compute_total(value, details_t(total_xact));
+ total_xact->total = 0;
+
+ total_xact->entry = last_entry;
+
+ for (amounts_map::const_iterator i = value.amounts.begin();
+ i != value.amounts.end();
+ i++) {
+ total_xact->amount = (*i).second;
+ total_xact->cost = (*i).second;
+
+ (*handler)(total_xact);
+ }
+
+ xact_temps.push_back(total_xact);
+}
+
+void changed_value_transactions::operator()(transaction_t * xact)
+{
+ if (last_xact) {
+ balance_t prev_bal;
+ balance_t cur_bal;
+ std::time_t current = xact ? xact->entry->date : std::time(NULL);
+ std::time_t prev_date = last_xact->entry->date;
+
+ format_t::compute_total(prev_bal, details_t(last_xact));
+
+ last_xact->entry->date = current;
+ format_t::compute_total(cur_bal, details_t(last_xact));
+ last_xact->entry->date = prev_date;
+
+ if (balance_t diff = cur_bal - prev_bal) {
+ modified_entry.date = current;
+
+ // jww (2004-08-07): What if there are multiple commodities?
+ assert(diff.amounts.size() == 1);
+ modified_xact.amount = diff.amount();
+ modified_xact.total = diff;
+ modified_xact.total.negate();
+
+ (*handler)(&modified_xact);
+ }
+ }
+
+ if (xact)
+ (*handler)(xact);
+
+ last_xact = xact;
+}
+
+void subtotal_transactions::flush()
+{
+ entry_t * entry = new entry_t;
+ entry->date = start;
+
+ char buf[256];
+ // jww (2004-08-10): allow for a format string here
+ std::strftime(buf, 255, "- %Y/%m/%d", std::gmtime(&finish));
+ entry->payee = buf;
+
+ entry_temps.push_back(entry);
+
+ for (balances_map::iterator i = balances.begin();
+ i != balances.end();
+ i++) {
+ transaction_t * xact = new transaction_t(entry, (*i).first);
+ xact->total = (*i).second;
+ balance_t result;
+ format_t::compute_total(result, details_t(xact));
+ xact->total = 0;
+
+ for (amounts_map::const_iterator j = result.amounts.begin();
+ j != result.amounts.end();
+ j++) {
+ xact->amount = (*j).second;
+ xact->cost = (*j).second;
+
+ (*handler)(xact);
+ }
+
+ xact_temps.push_back(xact);
+ }
+
+ balances.clear();
+}
+
+void subtotal_transactions::operator()(transaction_t * xact)
+{
+ if (balances.size() == 0) {
+ start = finish = xact->entry->date;
+ } else {
+ if (std::difftime(xact->entry->date, start) < 0)
+ start = xact->entry->date;
+ if (std::difftime(xact->entry->date, finish) > 0)
+ finish = xact->entry->date;
+ }
+
+ balances_map::iterator i = balances.find(xact->account);
+ if (i == balances.end())
+ balances.insert(balances_pair(xact->account, *xact));
+ else
+ (*i).second += *xact;
+}
+
+struct sum_in_account : public item_handler<transaction_t>
+{
+ virtual void operator()(transaction_t * xact) {
xact->account->value += *xact;
}
};