diff options
Diffstat (limited to 'balance.cc')
-rw-r--r-- | balance.cc | 128 |
1 files changed, 80 insertions, 48 deletions
@@ -9,6 +9,12 @@ namespace ledger { // Balance report. // +static bool show_current = false; +static bool show_cleared = false; +static bool show_children = false; +static bool show_empty = false; +static bool no_subtotals = false; + static inline bool matches(const std::list<pcre *>& regexps, const std::string& str) { for (std::list<pcre *>::const_iterator r = regexps.begin(); @@ -22,15 +28,37 @@ static inline bool matches(const std::list<pcre *>& regexps, return false; } -void report_balances(int argc, char *argv[], std::ostream& out) +void display_total(std::ostream& out, account * acct, + const std::map<account *, totals *>& balances) { - bool show_current = false; - bool show_cleared = false; - bool show_children = false; - bool show_empty = false; - bool no_subtotals = false; + std::map<account *, totals *>::const_iterator b = balances.find(acct); + if (b != balances.end()) { + totals * balance = (*b).second; + + if (balance && (show_empty || *balance)) { + out << *balance; + + if (acct->parent) { + for (account * a = acct; a; a = a->parent) + out << " "; + out << acct->name << std::endl; + } else { + out << " " << *acct << std::endl; + } + } + } + + for (account::iterator i = acct->children.begin(); + i != acct->children.end(); + i++) { + display_total(out, (*i).second, balances); + } +} +void report_balances(int argc, char **argv, std::ostream& out) +{ int c; + optind = 1; while (-1 != (c = getopt(argc, argv, "cCsSn"))) { switch (char(c)) { case 'c': show_current = true; break; @@ -62,16 +90,34 @@ void report_balances(int argc, char *argv[], std::ostream& out) // totals std::map<account *, totals *> balances; - std::time_t now = std::time(NULL); + totals total_balance; for (ledger_iterator i = ledger.begin(); i != ledger.end(); i++) { for (std::list<transaction *>::iterator x = (*i)->xacts.begin(); x != (*i)->xacts.end(); x++) { account * acct = (*x)->acct; - if (! regexps.empty() && ! matches(regexps, acct->name)) + + if (! regexps.empty()) { + if (show_children) { + bool match = false; + for (account * a = acct; a; a = a->parent) { + if (matches(regexps, a->name)) { + match = true; + break; + } + } + if (! match) + continue; + } + else if (! matches(regexps, acct->name)) { + continue; + } + } + else if (! show_children && acct->parent) { continue; + } while (acct) { totals * balance = NULL; @@ -84,16 +130,27 @@ void report_balances(int argc, char *argv[], std::ostream& out) balance = (*t).second; } + bool do_credit = false; + if (show_current) { if (difftime((*i)->date, now) < 0) - balance->credit((*x)->cost); + do_credit = true; } else if (show_cleared) { if ((*i)->cleared) - balance->credit((*x)->cost); + do_credit = true; } else { + do_credit = true; + } + + if (do_credit) { balance->credit((*x)->cost); + + // If this is a top-level account, then update the total + // running balance as well. + if (! acct->parent) + total_balance.credit((*x)->cost); } if (no_subtotals) @@ -104,6 +161,7 @@ void report_balances(int argc, char *argv[], std::ostream& out) } } +#if 0 // Print out the balance report header std::string which = "Future"; @@ -112,49 +170,23 @@ void report_balances(int argc, char *argv[], std::ostream& out) else if (show_cleared) which = "Cleared"; - std::cout.width(10); - std::cout << std::right << which << std::endl; - - // Walk through the accounts, given the balance report for each - - totals total_balance; - - for (accounts_iterator i = accounts.begin(); i != accounts.end(); i++) { - account * acct = (*i).second; + out.width(20); + out << std::right << which << std::endl + << "--------------------" << std::endl; +#endif - if (! regexps.empty() && ! matches(regexps, acct->name)) - continue; + // Walk through all the top-level accounts, given the balance + // report for each, and then for each of their children. - int depth = 0; - for (account * a = acct; a; a = a->parent) - depth++; - - if (! show_children && depth) - continue; - - totals * balance = balances[acct]; - - if (! show_empty && ! *balance) - continue; - - std::cout.width(10); - std::cout << *balance << " "; - - total_balance.credit(*balance); - - if (depth) { - while (--depth >= 0) - std::cout << " "; - std::cout << acct->name << std::endl; - } else { - std::cout << *acct << std::endl; - } - } + for (accounts_iterator i = accounts.begin(); i != accounts.end(); i++) + if (! (*i).second->parent) + display_total(out, (*i).second, balances); // Print the total of all the balances shown - std::cout.width(10); - std::cout << std::right << total_balance << std::endl; + if (! no_subtotals) + out << "--------------------" << std::endl + << total_balance << std::endl; // Free up temporary variables created on the heap |