fixed account display bug
This commit is contained in:
parent
2dc822291f
commit
05b2cc46fd
7 changed files with 140 additions and 86 deletions
59
format.cc
59
format.cc
|
|
@ -397,44 +397,59 @@ void format_transaction::operator()(transaction_t * xact) const
|
|||
last_xact = xact;
|
||||
}
|
||||
|
||||
|
||||
void format_account::operator()(account_t * account,
|
||||
const unsigned int max_depth,
|
||||
const bool report_top) const
|
||||
bool format_account::disp_subaccounts_p(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor,
|
||||
const account_t *& to_show)
|
||||
{
|
||||
// Don't output the account if only one child will be displayed
|
||||
// which shows the exact same amount. jww (2004-08-03): How do
|
||||
// compute the right figure? It should a value expression specified
|
||||
// by the user, to say, "If this expression is equivalent between a
|
||||
// parent account and a lone displayed child, then don't display the
|
||||
// parent."
|
||||
|
||||
if (bool output = ((report_top || account->parent != NULL) &&
|
||||
disp_pred_functor(account))) {
|
||||
int counted = 0;
|
||||
bool display = false;
|
||||
unsigned int counted = 0;
|
||||
|
||||
to_show = NULL;
|
||||
|
||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||
i != account->accounts.end();
|
||||
i++) {
|
||||
if (! (*i).second->total)
|
||||
// jww (2004-08-03): How do compute the right figure? It should a
|
||||
// value expression specified by the user, to say, "If this
|
||||
// expression is equivalent between a parent account and a lone
|
||||
// displayed child, then don't display the parent."
|
||||
|
||||
if (! (*i).second->total || ! disp_pred_functor((*i).second))
|
||||
continue;
|
||||
|
||||
if ((*i).second->total != account->total || counted > 0) {
|
||||
display = true;
|
||||
break;
|
||||
}
|
||||
to_show = (*i).second;
|
||||
counted++;
|
||||
}
|
||||
|
||||
if (counted == 1 && ! display)
|
||||
output = false;
|
||||
return display;
|
||||
}
|
||||
|
||||
if (output && (max_depth == 0 || account->depth <= max_depth)) {
|
||||
format.format_elements(output_stream, details_t(account));
|
||||
account->dflags |= ACCOUNT_DISPLAYED;
|
||||
}
|
||||
}
|
||||
bool format_account::display_account(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor)
|
||||
{
|
||||
// Never display the master account, or an account that has already
|
||||
// been displayed.
|
||||
if (! account->parent || account->dflags & ACCOUNT_DISPLAYED)
|
||||
return false;
|
||||
|
||||
// At this point, one of two possibilities exists: the account is a
|
||||
// leaf which matches the predicate restrictions; or it is a parent
|
||||
// and two or more children must be subtotaled; or it is a parent
|
||||
// and its child has been hidden by the predicate. So first,
|
||||
// determine if it is a parent that must be displayed regardless of
|
||||
// the predicate.
|
||||
|
||||
const account_t * account_to_show = NULL;
|
||||
if (disp_subaccounts_p(account, disp_pred_functor, account_to_show))
|
||||
return true;
|
||||
|
||||
return ! account_to_show && disp_pred_functor(account);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
24
format.h
24
format.h
|
|
@ -204,9 +204,20 @@ class format_account
|
|||
: output_stream(_output_stream), format(_format),
|
||||
disp_pred_functor(display_predicate) {}
|
||||
|
||||
void operator()(account_t * account,
|
||||
const unsigned int max_depth = 1,
|
||||
const bool report_top = false) const;
|
||||
static bool disp_subaccounts_p(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor,
|
||||
const account_t *& to_show);
|
||||
static bool display_account(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor);
|
||||
|
||||
void operator()(const account_t * account) const {
|
||||
if (display_account(account, disp_pred_functor)) {
|
||||
format.format_elements(output_stream, details_t(account));
|
||||
account->dflags |= ACCOUNT_DISPLAYED;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -241,11 +252,8 @@ class format_equity
|
|||
next_lines_format.format_elements(output_stream, details_t(&summary));
|
||||
}
|
||||
|
||||
void operator()(account_t * account,
|
||||
const unsigned int max_depth = 1,
|
||||
const bool report_top = false) const {
|
||||
if ((report_top || account->parent != NULL) &&
|
||||
disp_pred_functor(account)) {
|
||||
void operator()(const account_t * account) const {
|
||||
if (format_account::display_account(account, disp_pred_functor)) {
|
||||
next_lines_format.format_elements(output_stream, details_t(account));
|
||||
account->dflags |= ACCOUNT_DISPLAYED;
|
||||
total += account->value.quantity;
|
||||
|
|
|
|||
18
ledger.h
18
ledger.h
|
|
@ -41,9 +41,10 @@ class transaction_t
|
|||
amount_t cost;
|
||||
unsigned int flags;
|
||||
std::string note;
|
||||
balance_pair_t total;
|
||||
unsigned int index;
|
||||
unsigned int dflags;
|
||||
|
||||
mutable balance_pair_t total;
|
||||
mutable unsigned int index;
|
||||
mutable unsigned int dflags;
|
||||
|
||||
transaction_t(entry_t * _entry, account_t * _account)
|
||||
: entry(_entry), account(_account), flags(TRANSACTION_NORMAL),
|
||||
|
|
@ -105,15 +106,16 @@ class account_t
|
|||
account_t * parent;
|
||||
std::string name;
|
||||
std::string note;
|
||||
unsigned long depth;
|
||||
unsigned int depth;
|
||||
accounts_map accounts;
|
||||
transactions_list transactions;
|
||||
balance_pair_t value;
|
||||
balance_pair_t total;
|
||||
unsigned long ident;
|
||||
unsigned long dflags;
|
||||
|
||||
mutable balance_pair_t value;
|
||||
mutable balance_pair_t total;
|
||||
mutable unsigned long ident;
|
||||
mutable unsigned long dflags;
|
||||
mutable std::string _fullname;
|
||||
|
||||
static unsigned long next_ident;
|
||||
|
||||
account_t(account_t * _parent,
|
||||
|
|
|
|||
25
main.cc
25
main.cc
|
|
@ -570,11 +570,20 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
|
||||
if (display_predicate_string.empty()) {
|
||||
if (command == "b" && ! show_empty)
|
||||
if (command == "b") {
|
||||
if (! show_empty)
|
||||
display_predicate_string = "T";
|
||||
else if (command == "E")
|
||||
|
||||
if (! show_expanded) {
|
||||
if (! display_predicate_string.empty())
|
||||
display_predicate_string += "&";
|
||||
display_predicate_string += "!n";
|
||||
}
|
||||
}
|
||||
else if (command == "E") {
|
||||
display_predicate_string = "a";
|
||||
}
|
||||
}
|
||||
|
||||
if (! display_predicate_string.empty()) {
|
||||
#ifdef DEBUG
|
||||
|
|
@ -640,16 +649,12 @@ int main(int argc, char * argv[])
|
|||
format_t format(first_line_format);
|
||||
format_account formatter(std::cout, format, display_predicate.get());
|
||||
walk_accounts(journal->master, formatter, predicate.get(),
|
||||
xact_display_flags, show_subtotals, show_expanded ? 0 : 1,
|
||||
sort_order.get());
|
||||
xact_display_flags, show_subtotals, sort_order.get());
|
||||
|
||||
if (! display_predicate.get() ||
|
||||
item_predicate<account_t>(display_predicate.get())(journal->master)) {
|
||||
std::string end_format = "--------------------\n";
|
||||
format.reset(end_format + f);
|
||||
format_account(std::cout, format)(journal->master, true,
|
||||
display_predicate.get());
|
||||
}
|
||||
format_account(std::cout, format,
|
||||
display_predicate.get())(journal->master);
|
||||
}
|
||||
else if (command == "E") {
|
||||
format_t format(first_line_format);
|
||||
|
|
@ -657,7 +662,7 @@ int main(int argc, char * argv[])
|
|||
format_equity formatter(std::cout, format, nformat,
|
||||
display_predicate.get());
|
||||
walk_accounts(journal->master, formatter, predicate.get(),
|
||||
xact_display_flags, true, 0, sort_order.get());
|
||||
xact_display_flags, true, sort_order.get());
|
||||
}
|
||||
else if (command == "e") {
|
||||
format_t format(first_line_format);
|
||||
|
|
|
|||
34
valexpr.cc
34
valexpr.cc
|
|
@ -158,18 +158,46 @@ void node_t::compute(balance_t& result, const details_t& details) const
|
|||
break;
|
||||
|
||||
case CLEARED:
|
||||
if (details.entry)
|
||||
if (details.entry) {
|
||||
result = details.entry->state == entry_t::CLEARED;
|
||||
}
|
||||
else if (details.account) {
|
||||
bool all_clear = true;
|
||||
for (transactions_list::const_iterator i
|
||||
= details.account->transactions.begin();
|
||||
i != details.account->transactions.end();
|
||||
i++)
|
||||
if ((*i)->entry->state != entry_t::CLEARED) {
|
||||
all_clear = false;
|
||||
break;
|
||||
}
|
||||
result = all_clear;
|
||||
}
|
||||
break;
|
||||
|
||||
case REAL:
|
||||
if (details.xact)
|
||||
if (details.xact) {
|
||||
result = ! (details.xact->flags & TRANSACTION_VIRTUAL);
|
||||
}
|
||||
else if (details.account) {
|
||||
bool all_real = true;
|
||||
for (transactions_list::const_iterator i
|
||||
= details.account->transactions.begin();
|
||||
i != details.account->transactions.end();
|
||||
i++)
|
||||
if ((*i)->flags & TRANSACTION_VIRTUAL) {
|
||||
all_real = false;
|
||||
break;
|
||||
}
|
||||
result = all_real;
|
||||
}
|
||||
break;
|
||||
|
||||
case INDEX:
|
||||
if (details.xact)
|
||||
result = details.xact->index + 1;
|
||||
else if (details.account)
|
||||
result = details.account->depth - 1;
|
||||
break;
|
||||
|
||||
case F_ARITH_MEAN:
|
||||
|
|
@ -359,7 +387,7 @@ node_t * parse_term(std::istream& in)
|
|||
case 'd': node = new node_t(node_t::DATE); break;
|
||||
case 'X': node = new node_t(node_t::CLEARED); break;
|
||||
case 'R': node = new node_t(node_t::REAL); break;
|
||||
case 'i': node = new node_t(node_t::INDEX); break;
|
||||
case 'n': node = new node_t(node_t::INDEX); break;
|
||||
case 'B': node = new node_t(node_t::BALANCE); break;
|
||||
case 'T': node = new node_t(node_t::TOTAL); break;
|
||||
case 'C': node = new node_t(node_t::COST_TOTAL); break;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct node_t
|
|||
DATE,
|
||||
CLEARED,
|
||||
REAL,
|
||||
INDEX,
|
||||
INDEX, // for accounts, this is the DEPTH
|
||||
|
||||
// Item totals
|
||||
BALANCE,
|
||||
|
|
|
|||
18
walk.h
18
walk.h
|
|
@ -154,25 +154,22 @@ inline void sort_accounts(account_t * account,
|
|||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk__accounts(account_t * account,
|
||||
const Function& functor,
|
||||
const unsigned int max_depth)
|
||||
void walk__accounts(account_t * account, const Function& functor)
|
||||
{
|
||||
functor(account, max_depth);
|
||||
functor(account);
|
||||
|
||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||
i != account->accounts.end();
|
||||
i++)
|
||||
walk__accounts((*i).second, functor, max_depth);
|
||||
walk__accounts((*i).second, functor);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk__accounts_sorted(account_t * account,
|
||||
const Function& functor,
|
||||
const unsigned int max_depth,
|
||||
const node_t * sort_order)
|
||||
{
|
||||
functor(account, max_depth);
|
||||
functor(account);
|
||||
|
||||
accounts_deque accounts;
|
||||
|
||||
|
|
@ -187,7 +184,7 @@ void walk__accounts_sorted(account_t * account,
|
|||
for (accounts_deque::const_iterator i = accounts.begin();
|
||||
i != accounts.end();
|
||||
i++)
|
||||
walk__accounts_sorted(*i, functor, max_depth, sort_order);
|
||||
walk__accounts_sorted(*i, functor, sort_order);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
|
|
@ -222,7 +219,6 @@ void walk_accounts(account_t * account,
|
|||
const node_t * predicate,
|
||||
unsigned int flags,
|
||||
const bool calc_subtotals,
|
||||
const unsigned int max_depth,
|
||||
const node_t * sort_order = NULL)
|
||||
{
|
||||
item_predicate<transaction_t> pred_functor(predicate);
|
||||
|
|
@ -232,9 +228,9 @@ void walk_accounts(account_t * account,
|
|||
sum__accounts(account);
|
||||
|
||||
if (sort_order)
|
||||
walk__accounts_sorted<Function>(account, functor, max_depth, sort_order);
|
||||
walk__accounts_sorted<Function>(account, functor, sort_order);
|
||||
else
|
||||
walk__accounts<Function>(account, functor, max_depth);
|
||||
walk__accounts<Function>(account, functor);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue