From de3803d0277353520116f05c7b2357196a8cfe48 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 22 May 2010 15:40:38 -0400 Subject: 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 --- src/output.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/output.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/report.cc | 16 ++++++++++++++- 3 files changed, 144 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/output.cc b/src/output.cc index 30775310..e3aa9f4a 100644 --- a/src/output.cc +++ b/src/output.cc @@ -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::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::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::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::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 diff --git a/src/output.h b/src/output.h index 7618e567..3e70d9fe 100644 --- a/src/output.h +++ b/src/output.h @@ -103,6 +103,69 @@ public: virtual void operator()(account_t& account); }; +class report_accounts : public item_handler +{ +protected: + report_t& report; + + std::map accounts; + + typedef std::map::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 +{ +protected: + report_t& report; + + std::map payees; + + typedef std::map::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 +{ +protected: + report_t& report; + + std::map commodities; + + typedef std::map::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 diff --git a/src/report.cc b/src/report.cc index 1180c019..509be8b1 100644 --- a/src/report.cc +++ b/src/report.cc @@ -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': -- cgit v1.2.3