The -X option now accepts price settings
For example, if you had 100 AU (onces of gold) and wanted to report it in dollars, but at a price of $997 per ounce, you could now easily say: ledger bal -X '$,AU=$997'
This commit is contained in:
parent
1dc21c2d34
commit
86dfc1e0be
7 changed files with 70 additions and 41 deletions
|
|
@ -1026,21 +1026,30 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm,
|
|||
return create(comm, details, name);
|
||||
}
|
||||
|
||||
void commodity_pool_t::parse_commodity_price(char * optarg)
|
||||
commodity_t *
|
||||
commodity_pool_t::parse_commodity_prices(const std::string& str,
|
||||
const bool add_prices,
|
||||
const optional<datetime_t>& moment)
|
||||
{
|
||||
char * equals = std::strchr(optarg, '=');
|
||||
if (! equals)
|
||||
return;
|
||||
scoped_array<char> buf(new char[str.length() + 1]);
|
||||
|
||||
optarg = skip_ws(optarg);
|
||||
while (equals > optarg && std::isspace(*(equals - 1)))
|
||||
equals--;
|
||||
std::strcpy(buf.get(), str.c_str());
|
||||
|
||||
std::string symbol(optarg, 0, equals - optarg);
|
||||
amount_t price(equals + 1);
|
||||
char * price = std::strchr(buf.get(), '=');
|
||||
if (price)
|
||||
*price++ = '\0';
|
||||
|
||||
if (commodity_t * commodity = find_or_create(symbol))
|
||||
commodity->add_price(CURRENT_TIME(), price);
|
||||
if (commodity_t * commodity = find_or_create(trim_ws(buf.get()))) {
|
||||
if (price && add_prices) {
|
||||
for (char * p = std::strtok(price, ";");
|
||||
p;
|
||||
p = std::strtok(NULL, ";")) {
|
||||
commodity->add_price(moment ? *moment : CURRENT_TIME(), amount_t(p));
|
||||
}
|
||||
}
|
||||
return commodity;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
|
|
@ -567,7 +567,9 @@ public:
|
|||
commodity_t * find_or_create(commodity_t& comm,
|
||||
const annotation_t& details);
|
||||
|
||||
void parse_commodity_price(char * optarg);
|
||||
commodity_t * parse_commodity_prices(const std::string& str,
|
||||
const bool add_prices = true,
|
||||
const optional<datetime_t>& moment = none);
|
||||
};
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
|
|
@ -487,6 +487,14 @@ void global_scope_t::normalize_report_options(const string& verb)
|
|||
.on_with(string("?normalize"), rep.HANDLER(plot_total_format_).value);
|
||||
}
|
||||
|
||||
// If the --exchange (-X) option was used, parse out any final price
|
||||
// settings that may be there.
|
||||
if (rep.HANDLED(exchange_) &&
|
||||
rep.HANDLER(exchange_).str().find('=') != string::npos) {
|
||||
value_t(0L).exchange_commodities(rep.HANDLER(exchange_).str(),
|
||||
true, datetime_t(rep.terminus));
|
||||
}
|
||||
|
||||
long cols = 0;
|
||||
if (rep.HANDLED(columns_))
|
||||
cols = rep.HANDLER(columns_).value.to_long();
|
||||
|
|
|
|||
|
|
@ -129,33 +129,21 @@ value_t report_t::fn_market(call_scope_t& scope)
|
|||
{
|
||||
interactive_t args(scope, "a&ts");
|
||||
|
||||
if (args.has(2)) {
|
||||
scoped_array<char> buf(new char[args.get<string>(2).length() + 1]);
|
||||
std::strcpy(buf.get(), args.get<string>(2).c_str());
|
||||
|
||||
for (char * p = std::strtok(buf.get(), ",");
|
||||
p;
|
||||
p = std::strtok(NULL, ",")) {
|
||||
if (commodity_t * commodity = amount_t::current_pool->find(trim_ws(p))) {
|
||||
DEBUG("report.market", "Searching for value of " << args.value_at(0)
|
||||
<< " in terms of commodity " << commodity->symbol());
|
||||
value_t result =
|
||||
args.value_at(0).value(false, args.has(1) ?
|
||||
value_t result;
|
||||
optional<datetime_t> moment = (args.has(1) ?
|
||||
args.get<datetime_t>(1) :
|
||||
optional<datetime_t>(), *commodity);
|
||||
if (! result.is_null()) {
|
||||
DEBUG("report.market", "Market value is = " << result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value_t result =
|
||||
args.value_at(0).value(true, args.has(1) ?
|
||||
args.get<datetime_t>(1) : optional<datetime_t>());
|
||||
if (! result.is_null())
|
||||
return result;
|
||||
}
|
||||
optional<datetime_t>());
|
||||
|
||||
if (args.has(2))
|
||||
result = args.value_at(0).exchange_commodities(args.get<string>(2),
|
||||
/* add_prices= */ false,
|
||||
moment);
|
||||
else
|
||||
result = args.value_at(0).value(true, moment);
|
||||
|
||||
if (! result.is_null())
|
||||
return result;
|
||||
|
||||
return args.value_at(0);
|
||||
}
|
||||
|
||||
|
|
@ -608,7 +596,6 @@ option_t<report_t> * report_t::lookup_option(const char * p)
|
|||
case 's':
|
||||
OPT(set_account_);
|
||||
else OPT(set_payee_);
|
||||
else OPT(set_price_);
|
||||
else OPT(sort_);
|
||||
else OPT(sort_all_);
|
||||
else OPT(sort_xacts_);
|
||||
|
|
|
|||
|
|
@ -271,7 +271,6 @@ public:
|
|||
HANDLER(seed_).report(out);
|
||||
HANDLER(set_account_).report(out);
|
||||
HANDLER(set_payee_).report(out);
|
||||
HANDLER(set_price_).report(out);
|
||||
HANDLER(sort_).report(out);
|
||||
HANDLER(sort_all_).report(out);
|
||||
HANDLER(sort_xacts_).report(out);
|
||||
|
|
@ -714,7 +713,6 @@ public:
|
|||
OPTION(report_t, seed_);
|
||||
OPTION(report_t, set_account_);
|
||||
OPTION(report_t, set_payee_);
|
||||
OPTION(report_t, set_price_);
|
||||
|
||||
OPTION_(report_t, sort_, DO_(args) { // -S
|
||||
on_with(args[0].as_string(), args[1]);
|
||||
|
|
|
|||
21
src/value.cc
21
src/value.cc
|
|
@ -1228,6 +1228,27 @@ value_t value_t::value(const bool primary_only,
|
|||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
std::strcpy(buf.get(), commodities.c_str());
|
||||
|
||||
for (char * p = std::strtok(buf.get(), ",");
|
||||
p;
|
||||
p = std::strtok(NULL, ",")) {
|
||||
if (commodity_t * commodity =
|
||||
amount_t::current_pool->parse_commodity_prices(p, add_prices, moment)) {
|
||||
value_t result = value(false, moment, *commodity);
|
||||
if (! result.is_null())
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void value_t::in_place_reduce()
|
||||
{
|
||||
switch (type()) {
|
||||
|
|
|
|||
|
|
@ -449,6 +449,10 @@ public:
|
|||
const optional<datetime_t>& moment = none,
|
||||
const optional<commodity_t&>& in_terms_of = none) const;
|
||||
|
||||
value_t exchange_commodities(const std::string& commodities,
|
||||
const bool add_prices = false,
|
||||
const optional<datetime_t>& moment = none);
|
||||
|
||||
/**
|
||||
* Truth tests.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue