summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/amount.cc9
-rw-r--r--src/amount.h7
-rw-r--r--src/commodity.cc54
-rw-r--r--src/commodity.h4
-rw-r--r--src/filters.cc52
-rw-r--r--src/history.cc179
-rw-r--r--src/history.h61
-rw-r--r--src/iterators.cc104
-rw-r--r--test/baseline/feat-fixated-prices.test2
-rw-r--r--test/regress/25A099C9.test12
-rw-r--r--test/unit/t_commodity.cc2
11 files changed, 318 insertions, 168 deletions
diff --git a/src/amount.cc b/src/amount.cc
index 4d26a688..9704dd21 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -605,16 +605,13 @@ void amount_t::in_place_negate()
}
}
-amount_t amount_t::inverted() const
+void amount_t::in_place_invert()
{
if (! quantity)
throw_(amount_error, _("Cannot invert an uninitialized amount"));
- amount_t t(*this);
- t._dup();
- mpq_inv(MP(t.quantity), MP(t.quantity));
-
- return t;
+ _dup();
+ mpq_inv(MP(quantity), MP(quantity));
}
void amount_t::in_place_round()
diff --git a/src/amount.h b/src/amount.h
index 3a8e06b9..1db59b7e 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -327,7 +327,12 @@ public:
return *this;
}
- amount_t inverted() const;
+ amount_t inverted() const {
+ amount_t temp(*this);
+ temp.in_place_invert();
+ return temp;
+ }
+ void in_place_invert();
/** Yields an amount whose display precision when output is truncated
to the display precision of its commodity. This is normally the
diff --git a/src/commodity.cc b/src/commodity.cc
index 5e55db31..7d473d74 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -43,11 +43,20 @@ bool commodity_t::decimal_comma_by_default = false;
void commodity_t::add_price(const datetime_t& date, const amount_t& price,
const bool reflexive)
{
- if (! reflexive)
+ if (reflexive) {
+ DEBUG("history.find", "Marking "
+ << price.commodity().symbol() << " as a primary commodity");
+ price.commodity().add_flags(COMMODITY_PRIMARY);
+ } else {
+ DEBUG("history.find", "Marking " << symbol() << " as a primary commodity");
add_flags(COMMODITY_PRIMARY);
+ }
+
+ DEBUG("history.find", "Adding price: " << symbol()
+ << " for " << price << " on " << date);
+
pool().commodity_price_history.add_price(*this, date, price);
- DEBUG("commodity.prices.find", "Price added, clearing price_map");
base->price_map.clear(); // a price was added, invalid the map
}
@@ -55,27 +64,52 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity)
{
pool().commodity_price_history.remove_price(*this, commodity, date);
- DEBUG("commodity.prices.find", "Price removed, clearing price_map");
+ DEBUG("history.find", "Removing price: " << symbol() << " on " << date);
+
base->price_map.clear(); // a price was added, invalid the map
}
+void commodity_t::map_prices(function<void(datetime_t, const amount_t&)> fn,
+ const optional<datetime_t>& moment,
+ const optional<datetime_t>& _oldest)
+{
+ datetime_t when;
+ if (moment)
+ when = *moment;
+ else if (epoch)
+ when = *epoch;
+ else
+ when = CURRENT_TIME();
+
+ pool().commodity_price_history.map_prices(fn, *this, when, _oldest);
+}
+
optional<price_point_t>
commodity_t::find_price(const optional<commodity_t&>& commodity,
const optional<datetime_t>& moment,
const optional<datetime_t>& oldest) const
{
+ optional<commodity_t&> target;
+ if (commodity)
+ target = commodity;
+ else if (pool().default_commodity)
+ target = *pool().default_commodity;
+
+ if (target && *this == *target)
+ return none;
+
optional<base_t::time_and_commodity_t> pair =
base_t::time_and_commodity_t(base_t::optional_time_pair_t(moment, oldest),
commodity ? &(*commodity) : NULL);
- DEBUG("commodity.prices.find", "looking for memoized args: "
+ DEBUG("history.find", "looking for memoized args: "
<< (moment ? format_datetime(*moment) : "NONE") << ", "
<< (oldest ? format_datetime(*oldest) : "NONE") << ", "
<< (commodity ? commodity->symbol() : "NONE"));
{
base_t::memoized_price_map::iterator i = base->price_map.find(*pair);
if (i != base->price_map.end()) {
- DEBUG("commodity.prices.find", "found! returning: "
+ DEBUG("history.find", "found! returning: "
<< ((*i).second ? (*i).second->price : amount_t(0L)));
return (*i).second;
}
@@ -89,12 +123,6 @@ commodity_t::find_price(const optional<commodity_t&>& commodity,
else
when = CURRENT_TIME();
- optional<commodity_t&> target;
- if (commodity)
- target = commodity;
- else if (pool().default_commodity)
- target = *pool().default_commodity;
-
optional<price_point_t> point =
target ?
pool().commodity_price_history.find_price(*this, *target, when, oldest) :
@@ -102,13 +130,13 @@ commodity_t::find_price(const optional<commodity_t&>& commodity,
if (pair) {
if (base->price_map.size() > base_t::max_price_map_size) {
- DEBUG("commodity.prices.find",
+ DEBUG("history.find",
"price map has grown too large, clearing it by half");
for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++)
base->price_map.erase(base->price_map.begin());
}
- DEBUG("commodity.prices.find",
+ DEBUG("history.find",
"remembered: " << (point ? point->price : amount_t(0L)));
base->price_map.insert
(base_t::memoized_price_map::value_type(*pair, point));
diff --git a/src/commodity.h b/src/commodity.h
index a1ad0147..524daaab 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -271,6 +271,10 @@ public:
const bool reflexive = true);
void remove_price(const datetime_t& date, commodity_t& commodity);
+ void map_prices(function<void(datetime_t, const amount_t&)> fn,
+ const optional<datetime_t>& moment = none,
+ const optional<datetime_t>& _oldest = none);
+
optional<price_point_t>
find_price(const optional<commodity_t&>& commodity = none,
const optional<datetime_t>& moment = none,
diff --git a/src/filters.cc b/src/filters.cc
index 0c6222d7..6e52c40f 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -37,6 +37,7 @@
#include "report.h"
#include "compare.h"
#include "pool.h"
+#include "history.h"
namespace ledger {
@@ -688,6 +689,27 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date)
}
}
+namespace {
+ struct create_price_xact {
+ post_t& post;
+ const date_t& current;
+ price_map_t& all_prices;
+
+ create_price_xact(post_t& _post, const date_t& _current,
+ price_map_t& _all_prices)
+ : post(_post), current(_current), all_prices(_all_prices) {}
+
+ void operator()(datetime_t& date, const amount_t& price) {
+ if (date.date() > post.value_date() && date.date() < current) {
+ DEBUG("filters.revalued",
+ post.value_date() << " < " << date << " < " << current);
+ DEBUG("filters.revalued", "inserting " << price << " at " << date);
+ all_prices.insert(price_map_t::value_type(date, price));
+ }
+ }
+ };
+}
+
void changed_value_posts::output_intermediate_prices(post_t& post,
const date_t& current)
{
@@ -754,38 +776,17 @@ void changed_value_posts::output_intermediate_prices(post_t& post,
// fall through...
case value_t::BALANCE: {
-#if 0
- // jww (2012-03-04): TODO
- commodity_t::history_map all_prices;
+ price_map_t all_prices;
foreach (const balance_t::amounts_map::value_type& amt_comm,
- display_total.as_balance().amounts) {
- if (optional<commodity_t::varied_history_t&> hist =
- amt_comm.first->varied_history()) {
- foreach
- (const commodity_t::history_by_commodity_map::value_type& comm_hist,
- hist->histories) {
- foreach (const commodity_t::history_map::value_type& price,
- comm_hist.second.prices) {
- if (price.first.date() > post.value_date() &&
- price.first.date() < current) {
- DEBUG("filters.revalued", post.value_date() << " < "
- << price.first.date() << " < " << current);
- DEBUG("filters.revalued", "inserting "
- << price.second << " at " << price.first.date());
- all_prices.insert(price);
- }
- }
- }
- }
- }
+ display_total.as_balance().amounts)
+ amt_comm.first->map_prices(create_price_xact(post, current, all_prices));
// Choose the last price from each day as the price to use
typedef std::map<const date_t, bool> date_map;
date_map pricing_dates;
- BOOST_REVERSE_FOREACH
- (const commodity_t::history_map::value_type& price, all_prices) {
+ BOOST_REVERSE_FOREACH(const price_map_t::value_type& price, all_prices) {
// This insert will fail if a later price has already been inserted
// for that date.
DEBUG("filters.revalued",
@@ -799,7 +800,6 @@ void changed_value_posts::output_intermediate_prices(post_t& post,
output_revaluation(post, price.first);
last_total = repriced_total;
}
-#endif
break;
}
default:
diff --git a/src/history.cc b/src/history.cc
index a3d9139b..95ed584f 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -67,6 +67,9 @@ void commodity_history_t::add_price(const commodity_t& source,
if (! result.second) {
// There is already an entry for this moment, so update it
(*result.first).second = price;
+ } else {
+ last_reftime = none; // invalidate the FGraph cache
+ last_oldest = none;
}
}
@@ -82,64 +85,128 @@ void commodity_history_t::remove_price(const commodity_t& source,
// jww (2012-03-04): If it fails, should we give a warning?
prices.erase(date);
+
+ last_reftime = none; // invalidate the FGraph cache
+ last_oldest = none;
+}
+
+void commodity_history_t::map_prices(function<void(datetime_t,
+ const amount_t&)> fn,
+ const commodity_t& source,
+ const datetime_t& moment,
+ const optional<datetime_t>& _oldest)
+{
+ vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
+
+ reftime = moment;
+ oldest = _oldest;
+
+ graph_traits<FGraph>::adjacency_iterator f_vi, f_vend;
+ for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) {
+ std::pair<Graph::edge_descriptor, bool> edgePair = edge(sv, *f_vi, fg);
+ Graph::edge_descriptor edge = edgePair.first;
+
+ const price_map_t& prices(get(ratiomap, edge));
+
+ foreach (const price_map_t::value_type& pair, prices) {
+ const datetime_t& when(pair.first);
+
+ if ((! _oldest || 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)));
+ }
+ fn(when, pair.second);
+ }
+ }
+ }
}
optional<price_point_t>
commodity_history_t::find_price(const commodity_t& source,
const datetime_t& moment,
- const optional<datetime_t>& oldest)
+ const optional<datetime_t>& _oldest)
{
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
- // Filter out edges which came into being after the reference time
- FGraph fg(price_graph,
- recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
- (get(edge_weight, price_graph), pricemap, ratiomap,
- moment, oldest));
-
+ DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol());
+#if defined(DEBUG_ON)
+ if (source.has_flags(COMMODITY_PRIMARY))
+ DEBUG("history.find", "sv commodity is primary");
+#endif
+ DEBUG("history.find", "tv commodity = none ");
+
datetime_t most_recent = moment;
amount_t price;
+ reftime = moment;
+ oldest = _oldest;
+
graph_traits<FGraph>::adjacency_iterator f_vi, f_vend;
for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) {
std::pair<Graph::edge_descriptor, bool> edgePair = edge(sv, *f_vi, fg);
Graph::edge_descriptor edge = edgePair.first;
+ DEBUG("history.find", "u commodity = " << get(namemap, sv)->symbol());
+ DEBUG("history.find", "v commodity = " << get(namemap, *f_vi)->symbol());
+
const price_point_t& point(get(pricemap, edge));
if (price.is_null() || point.when > most_recent) {
most_recent = point.when;
price = point.price;
}
+
+ DEBUG("history.find", "price was = " << price.unrounded());
+
+ if (price.commodity() == source) {
+ 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.find", "price is = " << price.unrounded());
}
- if (price.is_null())
+ last_reftime = reftime; // invalidate the FGraph cache
+ last_oldest = oldest;
+
+ if (price.is_null()) {
+ DEBUG("history.find", "there is no final price");
return none;
- else
+ } else {
+ DEBUG("history.find", "final price is = " << price.unrounded());
return price_point_t(most_recent, price);
+ }
}
optional<price_point_t>
commodity_history_t::find_price(const commodity_t& source,
const commodity_t& target,
const datetime_t& moment,
- const optional<datetime_t>& oldest)
+ const optional<datetime_t>& _oldest)
{
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*target.graph_index(), price_graph);
- // Filter out edges which came into being after the reference time
- FGraph fg(price_graph,
- recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
- (get(edge_weight, price_graph), pricemap, ratiomap,
- moment, oldest));
-
+ DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol());
+ DEBUG("history.find", "tv commodity = " << get(namemap, tv)->symbol());
+
std::vector<vertex_descriptor> predecessors(num_vertices(fg));
std::vector<long> distances(num_vertices(fg));
PredecessorMap predecessorMap(&predecessors[0]);
DistanceMap distanceMap(&distances[0]);
+ reftime = moment;
+ oldest = _oldest;
+
dijkstra_shortest_paths(fg, /* start= */ sv,
predecessor_map(predecessorMap)
.distance_map(distanceMap)
@@ -149,7 +216,7 @@ commodity_history_t::find_price(const commodity_t& source,
datetime_t least_recent = moment;
amount_t price;
- FNameMap ptrs = get(vertex_name, fg);
+ const commodity_t * last_target = &target;
vertex_descriptor v = tv;
for (vertex_descriptor u = predecessorMap[v];
@@ -161,73 +228,85 @@ commodity_history_t::find_price(const commodity_t& source,
const price_point_t& point(get(pricemap, edge));
- const commodity_t * last_source = &source;
-
bool first_run = false;
if (price.is_null()) {
least_recent = point.when;
- price = point.price;
first_run = true;
}
else if (point.when < least_recent) {
least_recent = point.when;
}
- DEBUG("history.find", "u commodity = " << get(ptrs, u)->symbol());
- DEBUG("history.find", "v commodity = " << get(ptrs, v)->symbol());
- DEBUG("history.find", "last source = " << last_source->symbol());
+ DEBUG("history.find", "u commodity = " << get(namemap, u)->symbol());
+ DEBUG("history.find", "v commodity = " << get(namemap, v)->symbol());
+ DEBUG("history.find", "last target = " << last_target->symbol());
// Determine which direction we are converting in
amount_t pprice(point.price);
- DEBUG("history.find", "pprice = " << pprice);
+ DEBUG("history.find", "pprice = " << pprice.unrounded());
- DEBUG("history.find", "price was = " << price);
if (! first_run) {
- if (pprice.commodity() == *last_source)
+ DEBUG("history.find", "price was = " << price.unrounded());
+ if (pprice.commodity() != *last_target)
price *= pprice.inverted();
else
price *= pprice;
}
- else if (price.commodity() == *last_source) {
- price = price.inverted();
+ else if (pprice.commodity() != *last_target) {
+ price = pprice.inverted();
+ }
+ else {
+ price = pprice;
}
- DEBUG("history.find", "price is = " << price);
+ DEBUG("history.find", "price is = " << price.unrounded());
- if (*last_source == *get(ptrs, v))
- last_source = get(ptrs, u);
+ if (*last_target == *get(namemap, v))
+ last_target = get(namemap, u);
else
- last_source = get(ptrs, v);
+ last_target = get(namemap, v);
+
+ DEBUG("history.find", "last target now = " << last_target->symbol());
}
- price.set_commodity(const_cast<commodity_t&>(target));
- DEBUG("history.find", "final price is = " << price);
+ last_reftime = reftime; // invalidate the FGraph cache
+ last_oldest = oldest;
- if (price.is_null())
+ if (price.is_null()) {
+ DEBUG("history.find", "there is no final price");
return none;
- else
+ } else {
+ price.set_commodity(const_cast<commodity_t&>(target));
+ DEBUG("history.find", "final price is = " << price.unrounded());
+
return price_point_t(least_recent, price);
+ }
}
+template <class Name>
+class label_writer {
+public:
+ label_writer(Name _name) : name(_name) {}
+
+ template <class VertexOrEdge>
+ void operator()(std::ostream& out, const VertexOrEdge& v) const {
+ out << "[label=\"" << name[v]->symbol() << "\"]";
+ }
+
+private:
+ Name name;
+};
+
void commodity_history_t::print_map(std::ostream& out,
const optional<datetime_t>& moment)
{
-#if 0
- dynamic_properties p;
- p.property("label", get(edge_weight, price_graph));
- p.property("weight", get(edge_weight, price_graph));
- p.property("node_id", get(vertex_index, price_graph));
-
if (moment) {
- // Filter out edges which came into being after the reference time
- FGraph fg(price_graph,
- recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
- (get(edge_weight, price_graph), pricemap, ratiomap,
- *moment));
- write_graphviz(out, fg, p);
+ reftime = *moment;
+ write_graphviz(out, fg, label_writer<FNameMap>(namemap));
+ last_reftime = reftime;
} else {
- write_graphviz(out, price_graph, p);
+ write_graphviz(out, price_graph,
+ label_writer<NameMap>(get(vertex_name, price_graph)));
}
-#endif
}
} // namespace ledger
diff --git a/src/history.h b/src/history.h
index 70831445..eaca07ac 100644
--- a/src/history.h
+++ b/src/history.h
@@ -70,36 +70,50 @@ public:
PricePointMap price_point;
PriceRatioMap ratios;
- datetime_t reftime;
- optional<datetime_t> oldest;
+ datetime_t * reftime;
+ optional<datetime_t> * last_reftime;
+ optional<datetime_t> * oldest;
+ optional<datetime_t> * last_oldest;
recent_edge_weight() { }
- recent_edge_weight(EdgeWeightMap _weight,
- PricePointMap _price_point,
- PriceRatioMap _ratios,
- datetime_t _reftime,
- const optional<datetime_t>& _oldest = none)
+ recent_edge_weight(EdgeWeightMap _weight,
+ PricePointMap _price_point,
+ PriceRatioMap _ratios,
+ datetime_t * _reftime,
+ optional<datetime_t> * _last_reftime,
+ optional<datetime_t> * _oldest,
+ optional<datetime_t> * _last_oldest)
: weight(_weight), price_point(_price_point), ratios(_ratios),
- reftime(_reftime), oldest(_oldest) { }
+ reftime(_reftime), last_reftime(_last_reftime),
+ oldest(_oldest), last_oldest(_last_oldest) { }
template <typename Edge>
bool operator()(const Edge& e) const
{
+ if (*last_reftime && *reftime == **last_reftime &&
+ *oldest == *last_oldest)
+ return get(weight, e) != std::numeric_limits<std::size_t>::max();
+
const price_map_t& prices(get(ratios, e));
- if (prices.empty())
+ if (prices.empty()) {
+ put(weight, e, std::numeric_limits<std::size_t>::max());
return false;
+ }
- price_map_t::const_iterator low = prices.upper_bound(reftime);
+ price_map_t::const_iterator low = prices.upper_bound(*reftime);
if (low != prices.end() && low == prices.begin()) {
+ put(weight, e, std::numeric_limits<std::size_t>::max());
return false;
} else {
--low;
- assert(((*low).first <= reftime));
+ assert(((*low).first <= *reftime));
- if (oldest && (*low).first < *oldest)
+ if (*oldest && (*low).first < **oldest) {
+ put(weight, e, std::numeric_limits<std::size_t>::max());
return false;
+ }
- long secs = (reftime - (*low).first).total_seconds();
+ long secs = (*reftime - (*low).first).total_seconds();
assert(secs >= 0);
put(weight, e, secs);
@@ -160,10 +174,24 @@ public:
PriceRatioMap> > FGraph;
typedef property_map<FGraph, vertex_name_t>::type FNameMap;
+ FGraph fg;
+ FNameMap namemap;
+
+ // jww (2012-03-05): Prevents threading
+ mutable datetime_t reftime;
+ mutable optional<datetime_t> last_reftime;
+ mutable optional<datetime_t> oldest;
+ mutable optional<datetime_t> last_oldest;
+
commodity_history_t()
: indexmap(get(vertex_index, price_graph)),
pricemap(get(edge_price_point, price_graph)),
- ratiomap(get(edge_price_ratio, price_graph)) {}
+ ratiomap(get(edge_price_ratio, price_graph)),
+ fg(price_graph,
+ recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
+ (get(edge_weight, price_graph), pricemap, ratiomap,
+ &reftime, &last_reftime, &oldest, &last_oldest)),
+ namemap(get(vertex_name, fg)) {}
void add_commodity(commodity_t& comm);
@@ -174,6 +202,11 @@ public:
const commodity_t& target,
const datetime_t& date);
+ void map_prices(function<void(datetime_t, const amount_t&)> fn,
+ const commodity_t& source,
+ const datetime_t& moment,
+ const optional<datetime_t>& _oldest = none);
+
optional<price_point_t>
find_price(const commodity_t& source,
const datetime_t& moment,
diff --git a/src/iterators.cc b/src/iterators.cc
index b7ed011e..b994d59a 100644
--- a/src/iterators.cc
+++ b/src/iterators.cc
@@ -75,6 +75,55 @@ void journal_posts_iterator::increment()
}
}
+namespace {
+ struct create_price_xact {
+ account_t * account;
+ temporaries_t& temps;
+ xacts_list& xact_temps;
+
+ std::map<string, xact_t *> xacts_by_commodity;
+
+ create_price_xact(account_t * _account, temporaries_t& _temps,
+ xacts_list& _xact_temps)
+ : account(_account), temps(_temps), xact_temps(_xact_temps) {}
+
+ void operator()(datetime_t& date, const amount_t& price) {
+ xact_t * xact;
+ string symbol = price.commodity().symbol();
+
+ std::map<string, xact_t *>::iterator i =
+ xacts_by_commodity.find(symbol);
+ if (i != xacts_by_commodity.end()) {
+ xact = (*i).second;
+ } else {
+ xact = &temps.create_xact();
+ xact_temps.push_back(xact);
+ xact->payee = symbol;
+ xact->_date = date.date();
+ xacts_by_commodity.insert
+ (std::pair<string, xact_t *>(symbol, xact));
+ }
+
+ bool post_already_exists = false;
+
+ foreach (post_t * post, xact->posts) {
+ if (post->date() == date.date() && post->amount == price) {
+ post_already_exists = true;
+ break;
+ }
+ }
+
+ if (! post_already_exists) {
+ post_t& temp = temps.create_post(*xact, account);
+ temp._date = date.date();
+ temp.amount = price;
+
+ temp.xdata().datetime = date;
+ }
+ }
+ };
+}
+
void posts_commodities_iterator::reset(journal_t& journal)
{
journal_posts.reset(journal);
@@ -88,57 +137,10 @@ void posts_commodities_iterator::reset(journal_t& journal)
commodities.insert(&comm);
}
- std::map<string, xact_t *> xacts_by_commodity;
-
-#if 0
- // jww (2012-03-04): TODO
- foreach (commodity_t * comm, commodities) {
- if (optional<commodity_t::varied_history_t&> history =
- comm->varied_history()) {
- account_t * account = journal.master->find_account(comm->symbol());
-
- foreach (commodity_t::history_by_commodity_map::value_type& pair,
- history->histories) {
- foreach (commodity_t::history_map::value_type& hpair,
- pair.second.prices) {
- xact_t * xact;
- string symbol = hpair.second.commodity().symbol();
-
- std::map<string, xact_t *>::iterator i =
- xacts_by_commodity.find(symbol);
- if (i != xacts_by_commodity.end()) {
- xact = (*i).second;
- } else {
- xact = &temps.create_xact();
- xact_temps.push_back(xact);
- xact->payee = symbol;
- xact->_date = hpair.first.date();
- xacts_by_commodity.insert
- (std::pair<string, xact_t *>(symbol, xact));
- }
-
- bool post_already_exists = false;
-
- foreach (post_t * post, xact->posts) {
- if (post->_date == hpair.first.date() &&
- post->amount == hpair.second) {
- post_already_exists = true;
- break;
- }
- }
-
- if (! post_already_exists) {
- post_t& temp = temps.create_post(*xact, account);
- temp._date = hpair.first.date();
- temp.amount = hpair.second;
-
- temp.xdata().datetime = hpair.first;
- }
- }
- }
- }
- }
-#endif
+ foreach (commodity_t * comm, commodities)
+ comm->map_prices
+ (create_price_xact(journal.master->find_account(comm->symbol()),
+ temps, xact_temps));
xacts.reset(xact_temps.begin(), xact_temps.end());
diff --git a/test/baseline/feat-fixated-prices.test b/test/baseline/feat-fixated-prices.test
index f4370870..4767d866 100644
--- a/test/baseline/feat-fixated-prices.test
+++ b/test/baseline/feat-fixated-prices.test
@@ -1,3 +1,5 @@
+P 1989/01/15 12:00:00 GAL $3
+
1990/01/01 Payee
Expenses:Gas 100 GAL {=$2}
Liabilities:MasterCard $-200
diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test
index fc06449b..48b6814e 100644
--- a/test/regress/25A099C9.test
+++ b/test/regress/25A099C9.test
@@ -2,16 +2,16 @@ test -f $sourcepath/src/amount.h reg -> 7
__ERROR__
While parsing file "$sourcepath/src/amount.h", line 66:
Error: No quantity specified for amount
-While parsing file "$sourcepath/src/amount.h", line 726:
+While parsing file "$sourcepath/src/amount.h", line 731:
Error: Invalid date/time: line amount_t amoun
-While parsing file "$sourcepath/src/amount.h", line 732:
+While parsing file "$sourcepath/src/amount.h", line 737:
Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/src/amount.h", line 738:
+While parsing file "$sourcepath/src/amount.h", line 743:
Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/src/amount.h", line 744:
+While parsing file "$sourcepath/src/amount.h", line 749:
Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/src/amount.h", line 750:
+While parsing file "$sourcepath/src/amount.h", line 755:
Error: Invalid date/time: line std::ostream&
-While parsing file "$sourcepath/src/amount.h", line 757:
+While parsing file "$sourcepath/src/amount.h", line 762:
Error: Invalid date/time: line std::istream&
end test
diff --git a/test/unit/t_commodity.cc b/test/unit/t_commodity.cc
index dc64dcfb..6a6f27aa 100644
--- a/test/unit/t_commodity.cc
+++ b/test/unit/t_commodity.cc
@@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(testPriceHistory)
amt = x1.value(CURRENT_TIME(), euro);
BOOST_CHECK(amt);
- BOOST_CHECK_EQUAL(string("EUR 1366.87"), amt->rounded().to_string());
+ BOOST_CHECK_EQUAL(string("EUR 1787.50"), amt->rounded().to_string());
// Add a newer Euro pricing
aapl.add_price(jan17_07, amount_t("EUR 23.00"));