summaryrefslogtreecommitdiff
path: root/balance.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2003-09-30 03:22:38 +0000
committerJohn Wiegley <johnw@newartisans.com>2003-09-30 03:22:38 +0000
commitef6161fefb09253b9de6d228c92ce41b3a0063dc (patch)
tree513811f9b3aad8617d8795b4715c8448fb26afab /balance.cc
parent7bf86bc48a564ffffa46461c15ae2ab34b258fe8 (diff)
downloadfork-ledger-ef6161fefb09253b9de6d228c92ce41b3a0063dc.tar.gz
fork-ledger-ef6161fefb09253b9de6d228c92ce41b3a0063dc.tar.bz2
fork-ledger-ef6161fefb09253b9de6d228c92ce41b3a0063dc.zip
*** empty log message ***
Diffstat (limited to 'balance.cc')
-rw-r--r--balance.cc128
1 files changed, 80 insertions, 48 deletions
diff --git a/balance.cc b/balance.cc
index fd09bae1..b67c5365 100644
--- a/balance.cc
+++ b/balance.cc
@@ -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