Added "value" sub-directive for commodity directive

This commit is contained in:
John Wiegley 2012-03-06 03:18:10 -06:00
parent eb3591f898
commit 97d68ebc8c
6 changed files with 81 additions and 19 deletions

View file

@ -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);
}

View file

@ -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,

View file

@ -35,6 +35,7 @@
#include "commodity.h"
#include "annotate.h"
#include "pool.h"
#include "scope.h"
namespace ledger {
@ -84,6 +85,28 @@ void commodity_t::map_prices(function<void(datetime_t, const amount_t&)> fn,
pool().commodity_price_history.map_prices(fn, *this, when, _oldest);
}
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,
@ -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) :

View file

@ -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);
@ -267,6 +277,10 @@ public:
const optional<datetime_t>& moment = none,
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,

View file

@ -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

View file

@ -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