diff options
-rw-r--r-- | src/pool.cc | 72 | ||||
-rw-r--r-- | src/pool.h | 6 | ||||
-rw-r--r-- | src/report.cc | 15 | ||||
-rw-r--r-- | src/report.h | 1 |
4 files changed, 94 insertions, 0 deletions
diff --git a/src/pool.cc b/src/pool.cc index 6b422351..ad97a9c6 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -364,4 +364,76 @@ commodity_pool_t::parse_price_expression(const std::string& str, return NULL; } +void commodity_pool_t::print_pricemap(std::ostream& out, + const keep_details_t& keep, + const optional<datetime_t>& moment) +{ + typedef std::map<commodity_t *, commodity_t *> comm_map_t; + + comm_map_t comm_map; + + foreach (const commodities_map::value_type& comm_pair, commodities) { + commodity_t * comm(&comm_pair.second->strip_annotations(keep)); + comm_map.insert(comm_map_t::value_type(comm, NULL)); + } + + out << "digraph commodities {\n"; + + foreach (const comm_map_t::value_type& comm_pair, comm_map) { + commodity_t * comm(comm_pair.first); + if (comm->has_flags(COMMODITY_BUILTIN)) + continue; + + out << " "; + if (commodity_t::symbol_needs_quotes(comm->symbol())) + out << comm->symbol() << ";\n"; + else + out << "\"" << comm->symbol() << "\";\n"; + + if (! comm->has_flags(COMMODITY_NOMARKET) && + (! commodity_pool_t::current_pool->default_commodity || + comm != commodity_pool_t::current_pool->default_commodity)) { + if (optional<commodity_t::varied_history_t&> vhist = + comm->varied_history()) { + foreach (const commodity_t::history_by_commodity_map::value_type& pair, + vhist->histories) { + datetime_t most_recent; + amount_t most_recent_amt; + foreach (const commodity_t::history_map::value_type& inner_pair, + pair.second.prices) { + if ((most_recent.is_not_a_date_time() || + inner_pair.first > most_recent) && + (! moment || inner_pair.first <= moment)) { + most_recent = inner_pair.first; + most_recent_amt = inner_pair.second; + } + } + + if (! most_recent.is_not_a_date_time()) { + out << " "; + if (commodity_t::symbol_needs_quotes(comm->symbol())) + out << comm->symbol(); + else + out << "\"" << comm->symbol() << "\""; + + out << " -> "; + + if (commodity_t::symbol_needs_quotes(pair.first->symbol())) + out << pair.first->symbol(); + else + out << "\"" << pair.first->symbol() << "\""; + + out << " [label=\"" + << most_recent_amt.number() << "\\n" + << format_date(most_recent.date(), FMT_WRITTEN) + << "\" fontcolor=\"#008e28\"];\n"; + } + } + } + } + } + + out << "}\n"; +} + } // namespace ledger @@ -131,6 +131,12 @@ public: const bool add_prices = true, const optional<datetime_t>& moment = none); + // Output the commodity price map for a given date as a DOT file + + void print_pricemap(std::ostream& out, + const keep_details_t& keep, + const optional<datetime_t>& moment = none); + #if defined(HAVE_BOOST_SERIALIZATION) private: /** Serialization. */ diff --git a/src/report.cc b/src/report.cc index 81234b0f..e51736fd 100644 --- a/src/report.cc +++ b/src/report.cc @@ -842,6 +842,18 @@ value_t report_t::echo_command(call_scope_t& scope) return true; } +value_t report_t::pricemap_command(call_scope_t& scope) +{ + interactive_t args(scope, "&s"); + std::ostream& out(output_stream); + + commodity_pool_t::current_pool->print_pricemap + (out, what_to_keep(), args.has(0) ? + optional<datetime_t>(datetime_t(parse_date(args.get<string>(0)))) : none); + + return true; +} + option_t<report_t> * report_t::lookup_option(const char * p) { switch (*p) { @@ -1415,6 +1427,9 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, HANDLER(prepend_width_).value.to_long()), *this, "#pricedb")); } + else if (is_eq(p, "pricemap")) { + return MAKE_FUNCTOR(report_t::pricemap_command); + } else if (is_eq(p, "payees")) { return WRAP_FUNCTOR(reporter<>(new report_payees(*this), *this, "#payees")); diff --git a/src/report.h b/src/report.h index 6fa238f0..99b8781b 100644 --- a/src/report.h +++ b/src/report.h @@ -198,6 +198,7 @@ public: value_t reload_command(call_scope_t&); value_t echo_command(call_scope_t& scope); + value_t pricemap_command(call_scope_t& scope); keep_details_t what_to_keep() { bool lots = HANDLED(lots) || HANDLED(lots_actual); |