diff options
-rw-r--r-- | src/annotate.cc | 22 | ||||
-rw-r--r-- | src/annotate.h | 6 | ||||
-rw-r--r-- | src/commodity.cc | 26 | ||||
-rw-r--r-- | src/commodity.h | 14 | ||||
-rw-r--r-- | src/textual.cc | 8 | ||||
-rw-r--r-- | test/baseline/dir-commodity-value.test | 24 |
6 files changed, 81 insertions, 19 deletions
diff --git a/src/annotate.cc b/src/annotate.cc index 83926587..d2e4976e 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -34,7 +34,6 @@ #include "amount.h" #include "commodity.h" #include "expr.h" -#include "scope.h" #include "annotate.h" #include "pool.h" @@ -263,24 +262,9 @@ annotated_commodity_t::find_price(const optional<commodity_t&>& commodity, DEBUG("commodity.price.find", "target commodity: " << target->symbol()); #endif - if (details.value_expr) { -#if defined(DEBUG_ON) - if (SHOW_DEBUG("commodity.price.find")) { - ledger::_log_buffer << "valuation expr: "; - details.value_expr->dump(ledger::_log_buffer); - DEBUG("commodity.price.find", ""); - } -#endif - call_scope_t call_args(*scope_t::default_scope); - - call_args.push_back(string_value(base_symbol())); - call_args.push_back(when); - if (commodity) - call_args.push_back(string_value(commodity->symbol())); - - return price_point_t(when, const_cast<expr_t&>(*details.value_expr) - .calc(call_args).to_amount()); - } + if (details.value_expr) + return find_price_from_expr(const_cast<expr_t&>(*details.value_expr), + commodity, when); return commodity_t::find_price(commodity, moment, oldest); } diff --git a/src/annotate.h b/src/annotate.h index f9d62c5b..38553752 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -247,6 +247,12 @@ public: return *ptr; } + virtual optional<expr_t> value_expr() const { + if (details.value_expr) + return details.value_expr; + return commodity_t::value_expr(); + } + optional<price_point_t> virtual find_price(const optional<commodity_t&>& commodity = none, const optional<datetime_t>& moment = none, diff --git a/src/commodity.cc b/src/commodity.cc index 565204fd..0543c973 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -35,6 +35,7 @@ #include "commodity.h" #include "annotate.h" #include "pool.h" +#include "scope.h" namespace ledger { @@ -85,6 +86,28 @@ void commodity_t::map_prices(function<void(datetime_t, const amount_t&)> fn, } optional<price_point_t> +commodity_t::find_price_from_expr(expr_t& expr, + const optional<commodity_t&>& commodity, + const datetime_t& moment) const +{ +#if defined(DEBUG_ON) + if (SHOW_DEBUG("commodity.price.find")) { + ledger::_log_buffer << "valuation expr: "; + expr.dump(ledger::_log_buffer); + DEBUG("commodity.price.find", ""); + } +#endif + call_scope_t call_args(*scope_t::default_scope); + + call_args.push_back(string_value(base_symbol())); + call_args.push_back(moment); + if (commodity) + call_args.push_back(string_value(commodity->symbol())); + + return price_point_t(moment, expr.calc(call_args).to_amount()); +} + +optional<price_point_t> commodity_t::find_price(const optional<commodity_t&>& commodity, const optional<datetime_t>& moment, const optional<datetime_t>& oldest) const @@ -125,6 +148,9 @@ commodity_t::find_price(const optional<commodity_t&>& commodity, else when = CURRENT_TIME(); + if (base->value_expr) + return find_price_from_expr(*base->value_expr, commodity, when); + optional<price_point_t> point = target ? pool().commodity_price_history.find_price(*this, *target, when, oldest) : diff --git a/src/commodity.h b/src/commodity.h index 5cf9c53d..3d36e35e 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -47,6 +47,8 @@ #ifndef _COMMODITY_H #define _COMMODITY_H +#include "expr.h" + namespace ledger { struct keep_details_t; @@ -113,6 +115,7 @@ protected: optional<string> note; optional<amount_t> smaller; optional<amount_t> larger; + optional<expr_t> value_expr; typedef std::pair<optional<datetime_t>, optional<datetime_t> > optional_time_pair_t; @@ -259,6 +262,13 @@ public: base->larger = arg; } + virtual optional<expr_t> value_expr() const { + return base->value_expr; + } + void set_value_expr(const optional<expr_t>& expr = none) { + base->value_expr = expr; + } + void add_price(const datetime_t& date, const amount_t& price, const bool reflexive = true); void remove_price(const datetime_t& date, commodity_t& commodity); @@ -268,6 +278,10 @@ public: const optional<datetime_t>& _oldest = none); optional<price_point_t> + find_price_from_expr(expr_t& expr, const optional<commodity_t&>& commodity, + const datetime_t& moment) const; + + optional<price_point_t> virtual find_price(const optional<commodity_t&>& commodity = none, const optional<datetime_t>& moment = none, const optional<datetime_t>& oldest = none) const; diff --git a/src/textual.cc b/src/textual.cc index b1df1fb8..cf15f048 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -134,6 +134,7 @@ namespace { void commodity_directive(char * line); void commodity_alias_directive(commodity_t& comm, string alias); + void commodity_value_directive(commodity_t& comm, string expr_str); void commodity_format_directive(commodity_t& comm, string format); void commodity_nomarket_directive(commodity_t& comm); void commodity_default_directive(commodity_t& comm); @@ -1018,6 +1019,8 @@ void instance_t::commodity_directive(char * line) string keyword(q); if (keyword == "alias") commodity_alias_directive(*commodity, b); + else if (keyword == "value") + commodity_value_directive(*commodity, b); else if (keyword == "format") commodity_format_directive(*commodity, b); else if (keyword == "nomarket") @@ -1036,6 +1039,11 @@ void instance_t::commodity_alias_directive(commodity_t& comm, string alias) commodity_pool_t::current_pool->alias(alias, comm); } +void instance_t::commodity_value_directive(commodity_t& comm, string expr_str) +{ + comm.set_value_expr(expr_t(expr_str)); +} + void instance_t::commodity_format_directive(commodity_t&, string format) { // jww (2012-02-27): A format specified this way should turn off diff --git a/test/baseline/dir-commodity-value.test b/test/baseline/dir-commodity-value.test new file mode 100644 index 00000000..5e8fe789 --- /dev/null +++ b/test/baseline/dir-commodity-value.test @@ -0,0 +1,24 @@ +commodity $ + value 10 EUR + +commodity USD + alias FOO + value 25 EUR + +2012-03-06 KFC + Expenses:Food $20.00 + Assets:Cash + +2012-03-08 KFC + Expenses:Food USD 750,00 + Assets:Cash + +2012-03-10 KFC + Expenses:Food USD 750,00 + Assets:Cash + +test reg food -X EUR --now=2012-03-15 +12-Mar-06 KFC Expenses:Food 200 EUR 200 EUR +12-Mar-08 KFC Expenses:Food 18750 EUR 18950 EUR +12-Mar-10 KFC Expenses:Food 18750 EUR 37700 EUR +end test |