summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-06 03:18:10 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-06 03:24:06 -0600
commit97d68ebc8cf2bf88feffaedd6873934dc785c411 (patch)
treeb19e73eb8860dda1bbf8358141ddf1afc2060b50
parenteb3591f898e194be0cb6c15107e8e41e9dd67206 (diff)
downloadfork-ledger-97d68ebc8cf2bf88feffaedd6873934dc785c411.tar.gz
fork-ledger-97d68ebc8cf2bf88feffaedd6873934dc785c411.tar.bz2
fork-ledger-97d68ebc8cf2bf88feffaedd6873934dc785c411.zip
Added "value" sub-directive for commodity directive
-rw-r--r--src/annotate.cc22
-rw-r--r--src/annotate.h6
-rw-r--r--src/commodity.cc26
-rw-r--r--src/commodity.h14
-rw-r--r--src/textual.cc8
-rw-r--r--test/baseline/dir-commodity-value.test24
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