Improved the behavior of -X

This commit is contained in:
John Wiegley 2012-03-09 20:02:53 -06:00
parent cbc7bd337b
commit 2df8edc71c
5 changed files with 190 additions and 11 deletions

View file

@ -185,6 +185,8 @@ typedef std::ostream::pos_type ostream_pos_type;
#include <boost/regex.hpp>
#endif // HAVE_BOOST_REGEX_UNICODE
#include <boost/tokenizer.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>

View file

@ -1436,21 +1436,96 @@ value_t value_t::exchange_commodities(const std::string& commodities,
const bool add_prices,
const optional<datetime_t>& moment)
{
scoped_array<char> buf(new char[commodities.length() + 1]);
if (type() == SEQUENCE) {
value_t temp;
foreach (value_t& value, as_sequence_lval())
temp.push_back(value.exchange_commodities(commodities, add_prices, moment));
return temp;
}
std::strcpy(buf.get(), commodities.c_str());
// If we are repricing to just a single commodity, with no price
// expression, skip the expensive logic below.
if (commodities.find(',') == string::npos &&
commodities.find('=') == string::npos)
return value(moment, *commodity_pool_t::current_pool->find_or_create(commodities));
for (char * p = std::strtok(buf.get(), ",");
p;
p = std::strtok(NULL, ",")) {
if (commodity_t * commodity =
commodity_pool_t::current_pool->parse_price_expression(p, add_prices,
moment)) {
value_t result = value(moment, *commodity);
if (! result.is_null())
return result;
std::vector<commodity_t *> comms;
std::vector<bool> force;
typedef tokenizer<char_separator<char> > tokenizer;
tokenizer tokens(commodities, char_separator<char>(","));
foreach (const string& name, tokens) {
string::size_type name_len = name.length();
if (commodity_t * commodity = commodity_pool_t::current_pool
->parse_price_expression(name[name_len - 1] == '!' ?
string(name, 0, name_len - 1) :
name, add_prices, moment)) {
DEBUG("commodity.exchange", "Pricing for commodity: " << commodity->symbol());
comms.push_back(&commodity->referent());
force.push_back(name[name_len - 1] == '!');
}
}
int index = 0;
foreach (commodity_t * comm, comms) {
switch (type()) {
case AMOUNT:
DEBUG("commodity.exchange", "We have an amount: " << as_amount_lval());
if (! force[index] &&
std::find(comms.begin(), comms.end(),
&as_amount_lval().commodity().referent()) != comms.end())
break;
DEBUG("commodity.exchange", "Referent doesn't match, pricing...");
if (optional<amount_t> val = as_amount_lval().value(moment, *comm)) {
DEBUG("commodity.exchange", "Re-priced amount is: " << *val);
return *val;
}
DEBUG("commodity.exchange", "Was unable to find a price");
break;
case BALANCE: {
balance_t temp;
bool repriced = false;
DEBUG("commodity.exchange", "We have a balance: " << as_balance_lval());
foreach (const balance_t::amounts_map::value_type& pair,
as_balance_lval().amounts) {
DEBUG("commodity.exchange", "We have a balance amount of commodity: "
<< pair.first->symbol() << " == "
<< pair.second.commodity().symbol());
if (! force[index] &&
std::find(comms.begin(), comms.end(),
&pair.first->referent()) != comms.end()) {
temp += pair.second;
} else {
DEBUG("commodity.exchange", "Referent doesn't match, pricing...");
if (optional<amount_t> val = pair.second.value(moment, *comm)) {
DEBUG("commodity.exchange", "Re-priced member amount is: " << *val);
temp += *val;
repriced = true;
} else {
DEBUG("commodity.exchange", "Was unable to find price");
temp += pair.second;
}
}
}
if (repriced) {
DEBUG("commodity.exchange", "Re-priced balance is: " << temp);
return temp;
}
}
default:
break;
}
++index;
}
return *this;
}

View file

@ -149,6 +149,8 @@ class RegressFile(object):
harness.success()
else:
harness.failure(os.path.basename(self.filename))
print "STDERR:"
print p.stderr.read()
else:
if success: print
if test['exitcode']:

View file

@ -47,6 +47,63 @@
Assets:Brokerage -155 A [2009/01/06]
test reg --exchange=' C, A '
09-Jan-01 January 1st, 2009 (1) Assets:Brokerage 100 A 100 A
Assets:Brokerage -50 A 50 A
09-Jan-01 January 1st, 2009 (2) Assets:Brokerage 100 A 150 A
Assets:Brokerage -75 A 75 A
09-Jan-01 January 1st, 2009 (3) Assets:Brokerage 100 A 175 A
Assets:Brokerage -100 A 75 A
09-Jan-02 Commodities revalued <Revalued> 225 A
-1800 C 300 A
-1800 C
09-Jan-02 January 2nd, 2009 Assets:Brokerage 500 C 300 A
-1300 C
Assets:Brokerage -500 C 300 A
-1800 C
09-Jan-03 January 3rd, 2009 Assets:Brokerage 600 C 300 A
-1200 C
Assets:Brokerage -600 C 300 A
-1800 C
09-Jan-04 January 4th, 2009 Assets:Brokerage 300 A 600 A
-1800 C
Assets:Brokerage -2400 C 600 A
-4200 C
09-Jan-05 January 5th, 2009 Assets:Brokerage 1280 C 600 A
-2920 C
Assets:Brokerage -1280 C 600 A
-4200 C
09-Jan-06 Commodities revalued <Revalued> 2040 C 600 A
-2160 C
09-Jan-06 January 6th, 2009 Assets:Brokerage 155 A 755 A
-2160 C
Assets:Brokerage -186 C 755 A
-2346 C
09-Jan-07 Commodities revalued <Revalued> -86 C 755 A
-2432 C
09-Jan-07 January 7th, 2009 Assets:Brokerage 155 A 910 A
-2432 C
Assets:Brokerage -200 C 910 A
-2632 C
09-Jan-08 Commodities revalued <Revalued> -5613 C 910 A
-8245 C
09-Jan-08 January 8th, 2009 Assets:Brokerage 155 A 1065 A
-8245 C
Assets:Brokerage -200 C 1065 A
-8445 C
09-Jan-09 Commodities revalued <Revalued> -2800 C 1065 A
-11245 C
09-Jan-09 January 9th, 2009 Assets:Brokerage 200 C 1065 A
-11045 C
Assets:Brokerage -155 A 910 A
-11045 C
09-Jan-10 January 10th, 2009 Assets:Brokerage 200 C 910 A
-10845 C
Assets:Brokerage -155 A 755 A
-10845 C
end test
test reg --exchange=' C!, A '
09-Jan-01 January 1st, 2009 (1) Assets:Brokerage 100 A 100 A
Assets:Brokerage -50 A 50 A
09-Jan-01 January 1st, 2009 (2) Assets:Brokerage 100 A 150 A

View file

@ -0,0 +1,43 @@
P 2012-03-01 EUR $2
P 2012-03-01 GBP $2
2012-03-05 KFC
Expenses:Food 10 EUR
Assets:Cash
2012-03-10 KFC
Expenses:Food 10 GBP
Assets:Cash
test reg food
12-Mar-05 KFC Expenses:Food 10 EUR 10 EUR
12-Mar-10 KFC Expenses:Food 10 GBP 10 EUR
10 GBP
end test
test reg food -V
12-Mar-05 KFC Expenses:Food $20 $20
12-Mar-10 KFC Expenses:Food $20 $40
end test
test reg food -X '$'
12-Mar-05 KFC Expenses:Food $20 $20
12-Mar-10 KFC Expenses:Food $20 $40
end test
test reg food -X '$,GBP'
12-Mar-05 KFC Expenses:Food $20 $20
12-Mar-10 KFC Expenses:Food 10 GBP $20
10 GBP
end test
test reg food -X '$!,GBP'
12-Mar-05 KFC Expenses:Food $20 $20
12-Mar-10 KFC Expenses:Food $20 $40
end test
test reg food -X '$,EUR'
12-Mar-05 KFC Expenses:Food 10 EUR 10 EUR
12-Mar-10 KFC Expenses:Food $20 $20
10 EUR
end test