Added new commands: acounts, payees, commodities

These three reports simply dump an unordered list (with the exception of
payees) shows all accounts, payees, and commodities represented in a
given report.  This can be used to easily generate per-entity report,
for example:

  ledger payees | \
  while read payee; do \
    echo ; echo $payee ; \
    ledger reg payee "$payee" ; \
  done
This commit is contained in:
John Wiegley 2010-05-22 15:40:38 -04:00
parent e3ba0117a3
commit de3803d027
3 changed files with 144 additions and 1 deletions

View file

@ -232,4 +232,70 @@ void format_accounts::operator()(account_t& account)
posted_accounts.push_back(&account);
}
void report_accounts::flush()
{
std::ostream& out(report.output_stream);
foreach (accounts_pair& entry, accounts)
out << *entry.first << '\n';
}
void report_accounts::operator()(post_t& post)
{
std::map<account_t *, bool>::iterator i = accounts.find(post.account);
if (i == accounts.end())
accounts.insert(accounts_pair(post.account, true));
}
void report_payees::flush()
{
std::ostream& out(report.output_stream);
foreach (payees_pair& entry, payees)
out << entry.first << '\n';
}
void report_payees::operator()(post_t& post)
{
std::map<string, bool>::iterator i = payees.find(post.xact->payee);
if (i == payees.end())
payees.insert(payees_pair(post.xact->payee, true));
}
void report_commodities::flush()
{
std::ostream& out(report.output_stream);
foreach (commodities_pair& entry, commodities)
out << *entry.first << '\n';
}
void report_commodities::operator()(post_t& post)
{
amount_t temp(post.amount.strip_annotations(report.what_to_keep()));
commodity_t& comm(temp.commodity());
std::map<commodity_t *, bool>::iterator i = commodities.find(&comm);
if (i == commodities.end())
commodities.insert(commodities_pair(&comm, true));
if (comm.has_annotation()) {
annotated_commodity_t& ann_comm(as_annotated_commodity(comm));
if (ann_comm.details.price) {
std::map<commodity_t *, bool>::iterator i =
commodities.find(&ann_comm.details.price->commodity());
if (i == commodities.end())
commodities.insert
(commodities_pair(&ann_comm.details.price->commodity(), true));
}
}
if (post.cost) {
amount_t temp_cost(post.cost->strip_annotations(report.what_to_keep()));
i = commodities.find(&temp_cost.commodity());
if (i == commodities.end())
commodities.insert(commodities_pair(&temp_cost.commodity(), true));
}
}
} // namespace ledger

View file

@ -103,6 +103,69 @@ public:
virtual void operator()(account_t& account);
};
class report_accounts : public item_handler<post_t>
{
protected:
report_t& report;
std::map<account_t *, bool> accounts;
typedef std::map<account_t *, bool>::value_type accounts_pair;
public:
report_accounts(report_t& _report) : report(_report) {
TRACE_CTOR(report_accounts, "report&");
}
virtual ~report_accounts() {
TRACE_DTOR(report_accounts);
}
virtual void flush();
virtual void operator()(post_t& post);
};
class report_payees : public item_handler<post_t>
{
protected:
report_t& report;
std::map<string, bool> payees;
typedef std::map<string, bool>::value_type payees_pair;
public:
report_payees(report_t& _report) : report(_report) {
TRACE_CTOR(report_payees, "report&");
}
virtual ~report_payees() {
TRACE_DTOR(report_payees);
}
virtual void flush();
virtual void operator()(post_t& post);
};
class report_commodities : public item_handler<post_t>
{
protected:
report_t& report;
std::map<commodity_t *, bool> commodities;
typedef std::map<commodity_t *, bool>::value_type commodities_pair;
public:
report_commodities(report_t& _report) : report(_report) {
TRACE_CTOR(report_commodities, "report&");
}
virtual ~report_commodities() {
TRACE_DTOR(report_commodities);
}
virtual void flush();
virtual void operator()(post_t& post);
};
} // namespace ledger
#endif // _OUTPUT_H

View file

@ -1222,6 +1222,12 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
case symbol_t::COMMAND:
switch (*p) {
case 'a':
if (is_eq(p, "accounts"))
return WRAP_FUNCTOR(reporter<>(new report_accounts(*this), *this,
"#accounts"));
break;
case 'b':
if (*(p + 1) == '\0' || is_eq(p, "bal") || is_eq(p, "balance")) {
return expr_t::op_t::wrap_functor
@ -1262,8 +1268,13 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
maybe_format(HANDLER(prepend_format_))),
*this, "#cleared"));
}
else if (is_eq(p, "convert"))
else if (is_eq(p, "convert")) {
return WRAP_FUNCTOR(convert_command);
}
else if (is_eq(p, "commodities")) {
return WRAP_FUNCTOR(reporter<>(new report_commodities(*this), *this,
"#commodities"));
}
break;
case 'e':
@ -1296,6 +1307,9 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
(new format_posts(*this, report_format(HANDLER(pricedb_format_)),
maybe_format(HANDLER(prepend_format_))),
*this, "#pricedb"));
else if (is_eq(p, "payees"))
return WRAP_FUNCTOR(reporter<>(new report_payees(*this), *this,
"#payees"));
break;
case 'r':