summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commodity.cc6
-rw-r--r--src/commodity.h3
-rw-r--r--src/filters.cc2
-rw-r--r--src/history.cc32
-rw-r--r--src/history.h3
-rw-r--r--src/pool.cc3
-rw-r--r--test/regress/786A3DD0.test17
7 files changed, 53 insertions, 13 deletions
diff --git a/src/commodity.cc b/src/commodity.cc
index 8f0dc100..0dad9a1a 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -72,7 +72,8 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity)
void commodity_t::map_prices(function<void(datetime_t, const amount_t&)> fn,
const datetime_t& moment,
- const datetime_t& _oldest)
+ const datetime_t& _oldest,
+ bool bidirectionally)
{
datetime_t when;
if (! moment.is_not_a_date_time())
@@ -82,7 +83,8 @@ void commodity_t::map_prices(function<void(datetime_t, const amount_t&)> fn,
else
when = CURRENT_TIME();
- pool().commodity_price_history.map_prices(fn, *this, when, _oldest);
+ pool().commodity_price_history.map_prices(fn, *this, when, _oldest,
+ bidirectionally);
}
optional<price_point_t>
diff --git a/src/commodity.h b/src/commodity.h
index bd1aedb9..148a3636 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -273,7 +273,8 @@ public:
void map_prices(function<void(datetime_t, const amount_t&)> fn,
const datetime_t& moment = datetime_t(),
- const datetime_t& _oldest = datetime_t());
+ const datetime_t& _oldest = datetime_t(),
+ bool bidirectionally = false);
optional<price_point_t>
find_price_from_expr(expr_t& expr, const commodity_t * commodity,
diff --git a/src/filters.cc b/src/filters.cc
index 9501856e..d5cb8ebb 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -776,7 +776,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post,
display_total.as_balance().amounts)
amt_comm.first->map_prices(insert_prices_in_map(all_prices),
datetime_t(current),
- datetime_t(post.value_date()));
+ datetime_t(post.value_date()), true);
// Choose the last price from each day as the price to use
typedef std::map<const date_t, bool> date_map;
diff --git a/src/history.cc b/src/history.cc
index fcb80d67..3767c1df 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -132,6 +132,8 @@ void commodity_history_t::add_price(const commodity_t& source,
const datetime_t& when,
const amount_t& price)
{
+ assert(source != price.commodity());
+
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*price.commodity().graph_index(), price_graph);
@@ -153,6 +155,8 @@ void commodity_history_t::remove_price(const commodity_t& source,
const commodity_t& target,
const datetime_t& date)
{
+ assert(source != target);
+
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*target.graph_index(), price_graph);
@@ -172,8 +176,11 @@ void commodity_history_t::map_prices(function<void(datetime_t,
const amount_t&)> fn,
const commodity_t& source,
const datetime_t& moment,
- const datetime_t& oldest)
+ const datetime_t& oldest,
+ bool bidirectionally)
{
+ DEBUG("history.map", "Mapping prices for source commodity: " << source);
+
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
FGraph fg(price_graph,
@@ -193,16 +200,23 @@ void commodity_history_t::map_prices(function<void(datetime_t,
foreach (const price_map_t::value_type& pair, prices) {
const datetime_t& when(pair.first);
+ DEBUG("history.map", "Price " << pair.second << " on " << when);
+
if ((oldest.is_not_a_date_time() || when >= oldest) && when <= moment) {
if (pair.second.commodity() == source) {
- amount_t price(pair.second);
- price.in_place_invert();
- if (source == *get(namemap, sv))
- price.set_commodity(const_cast<commodity_t&>(*get(namemap, *f_vi)));
- else
- price.set_commodity(const_cast<commodity_t&>(*get(namemap, sv)));
+ if (bidirectionally) {
+ amount_t price(pair.second);
+ price.in_place_invert();
+ if (source == *get(namemap, sv))
+ price.set_commodity(const_cast<commodity_t&>(*get(namemap, *f_vi)));
+ else
+ price.set_commodity(const_cast<commodity_t&>(*get(namemap, sv)));
+ DEBUG("history.map", "Inverted price is " << price);
+ fn(when, price);
+ }
+ } else {
+ fn(when, pair.second);
}
- fn(when, pair.second);
}
}
}
@@ -275,6 +289,8 @@ commodity_history_t::find_price(const commodity_t& source,
const datetime_t& moment,
const datetime_t& oldest)
{
+ assert(source != target);
+
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*target.graph_index(), price_graph);
diff --git a/src/history.h b/src/history.h
index 71cbad0c..af0d90f9 100644
--- a/src/history.h
+++ b/src/history.h
@@ -113,7 +113,8 @@ public:
void map_prices(function<void(datetime_t, const amount_t&)> fn,
const commodity_t& source,
const datetime_t& moment,
- const datetime_t& _oldest = datetime_t());
+ const datetime_t& _oldest = datetime_t(),
+ bool bidirectionally = false);
optional<price_point_t>
find_price(const commodity_t& source,
diff --git a/src/pool.cc b/src/pool.cc
index 0118a97d..d5494352 100644
--- a/src/pool.cc
+++ b/src/pool.cc
@@ -266,6 +266,9 @@ commodity_pool_t::exchange(const amount_t& amount,
amount_t per_unit_cost =
(is_per_unit || amount.is_realzero()) ? cost.abs() : (cost / amount).abs();
+ if (! cost.has_commodity())
+ per_unit_cost.clear_commodity();
+
DEBUG("commodity.prices.add", "exchange: per-unit-cost = " << per_unit_cost);
// Do not record commodity exchanges where amount's commodity has a
diff --git a/test/regress/786A3DD0.test b/test/regress/786A3DD0.test
new file mode 100644
index 00000000..051f6382
--- /dev/null
+++ b/test/regress/786A3DD0.test
@@ -0,0 +1,17 @@
+D 1000.00 EUR
+
+2011-02-27 * Australia
+ A -100.00 AUD @ 0.746 EUR
+ B
+
+2012-03-12 * Withdrawal
+ Assets:Cash USD 200.00
+ Expenses:Banking:Fees USD 2.50
+ Assets:Chequing CAD -203.42
+ Epenses:Banking:Fees CAD 2.00
+ Assets:Chqeuing CAD -2.00
+
+test pricedb
+P 2011/02/27 00:00:00 AUD 0.746 EUR
+P 2012/03/12 00:00:00 USD CAD 1.00454320987654321
+end test