Added --exchange (-x) option
This is like -V, except it lets you specify the goal commodity to report
in terms of, for example:
reg -x CAD
This commit is contained in:
parent
04fd1ae24c
commit
e124811d8a
15 changed files with 121 additions and 76 deletions
|
|
@ -128,6 +128,7 @@ See \fB\-\-basis\fR.
|
||||||
.It Fl \-end Pq Fl e
|
.It Fl \-end Pq Fl e
|
||||||
.It Fl \-equity
|
.It Fl \-equity
|
||||||
.It Fl \-exact
|
.It Fl \-exact
|
||||||
|
.It Fl \-exchange Ar COMM Pq Fl x
|
||||||
.It Fl \-file Ar FILE
|
.It Fl \-file Ar FILE
|
||||||
.It Fl \-first Ar INT
|
.It Fl \-first Ar INT
|
||||||
See \fB\-\-head\fR.
|
See \fB\-\-head\fR.
|
||||||
|
|
|
||||||
|
|
@ -509,13 +509,19 @@ void amount_t::in_place_unreduce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<amount_t> amount_t::value(const optional<datetime_t>& moment,
|
optional<amount_t>
|
||||||
const optional<commodity_t&>& in_terms_of) const
|
amount_t::value(const bool primary_only,
|
||||||
|
const optional<datetime_t>& moment,
|
||||||
|
const optional<commodity_t&>& in_terms_of) const
|
||||||
{
|
{
|
||||||
if (quantity) {
|
if (quantity) {
|
||||||
optional<price_point_t> point(commodity().find_price(in_terms_of, moment));
|
if (has_commodity() &&
|
||||||
if (point)
|
(! primary_only || commodity().has_flags(COMMODITY_PRIMARY)) &&
|
||||||
return (point->price * number()).rounded();
|
(! in_terms_of || commodity() != *in_terms_of)) {
|
||||||
|
optional<price_point_t> point(commodity().find_price(in_terms_of, moment));
|
||||||
|
if (point)
|
||||||
|
return (point->price * number()).rounded();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw_(amount_error, "Cannot determine value of an uninitialized amount");
|
throw_(amount_error, "Cannot determine value of an uninitialized amount");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,8 @@ public:
|
||||||
$100.00.
|
$100.00.
|
||||||
*/
|
*/
|
||||||
optional<amount_t>
|
optional<amount_t>
|
||||||
value(const optional<datetime_t>& moment = none,
|
value(const bool primary_only = true,
|
||||||
|
const optional<datetime_t>& moment = none,
|
||||||
const optional<commodity_t&>& in_terms_of = none) const;
|
const optional<commodity_t&>& in_terms_of = none) const;
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,8 @@ balance_t& balance_t::operator/=(const amount_t& amt)
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<balance_t>
|
optional<balance_t>
|
||||||
balance_t::value(const optional<datetime_t>& moment,
|
balance_t::value(const bool primary_only,
|
||||||
|
const optional<datetime_t>& moment,
|
||||||
const optional<commodity_t&>& in_terms_of) const
|
const optional<commodity_t&>& in_terms_of) const
|
||||||
{
|
{
|
||||||
optional<balance_t> temp;
|
optional<balance_t> temp;
|
||||||
|
|
@ -167,7 +168,8 @@ balance_t::value(const optional<datetime_t>& moment,
|
||||||
foreach (const amounts_map::value_type& pair, amounts) {
|
foreach (const amounts_map::value_type& pair, amounts) {
|
||||||
if (! temp)
|
if (! temp)
|
||||||
temp = balance_t();
|
temp = balance_t();
|
||||||
if (optional<amount_t> val = pair.second.value(moment, in_terms_of))
|
if (optional<amount_t> val = pair.second.value(primary_only, moment,
|
||||||
|
in_terms_of))
|
||||||
*temp += *val;
|
*temp += *val;
|
||||||
else
|
else
|
||||||
*temp += pair.second;
|
*temp += pair.second;
|
||||||
|
|
|
||||||
|
|
@ -353,8 +353,10 @@ public:
|
||||||
return *this = temp;
|
return *this = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<balance_t> value(const optional<datetime_t>& moment = none,
|
optional<balance_t>
|
||||||
const optional<commodity_t&>& in_terms_of = none) const;
|
value(const bool primary_only = false,
|
||||||
|
const optional<datetime_t>& moment = none,
|
||||||
|
const optional<commodity_t&>& in_terms_of = none) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truth tests. An balance may be truth test in two ways:
|
* Truth tests. An balance may be truth test in two ways:
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
void commodity_t::base_t::history_t::add_price(const commodity_t& source,
|
void commodity_t::base_t::history_t::add_price(commodity_t& source,
|
||||||
const datetime_t& date,
|
const datetime_t& date,
|
||||||
const amount_t& price,
|
const amount_t& price,
|
||||||
const bool reflexive)
|
const bool reflexive)
|
||||||
{
|
{
|
||||||
DEBUG("commodity.prices",
|
DEBUG("commodity.prices",
|
||||||
"add_price to " << source << " : " << date << ", " << price);
|
"add_price to " << source << " : " << date << ", " << price);
|
||||||
|
|
@ -50,10 +50,13 @@ void commodity_t::base_t::history_t::add_price(const commodity_t& source,
|
||||||
assert(result.second);
|
assert(result.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reflexive && ! price.commodity().has_flags(COMMODITY_NOMARKET)) {
|
if (reflexive) {
|
||||||
amount_t inverse = price.inverted();
|
if (! price.commodity().has_flags(COMMODITY_NOMARKET)) {
|
||||||
inverse.set_commodity(const_cast<commodity_t&>(source));
|
amount_t inverse = price.inverted();
|
||||||
price.commodity().add_price(date, inverse, false);
|
inverse.set_commodity(const_cast<commodity_t&>(source));
|
||||||
|
price.commodity().add_price(date, inverse, false);
|
||||||
|
}
|
||||||
|
source.add_flags(COMMODITY_PRIMARY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,10 +71,10 @@ bool commodity_t::base_t::history_t::remove_price(const datetime_t& date)
|
||||||
}
|
}
|
||||||
|
|
||||||
void commodity_t::base_t::varied_history_t::
|
void commodity_t::base_t::varied_history_t::
|
||||||
add_price(const commodity_t& source,
|
add_price(commodity_t& source,
|
||||||
const datetime_t& date,
|
const datetime_t& date,
|
||||||
const amount_t& price,
|
const amount_t& price,
|
||||||
const bool reflexive)
|
const bool reflexive)
|
||||||
{
|
{
|
||||||
optional<history_t&> hist = history(price.commodity());
|
optional<history_t&> hist = history(price.commodity());
|
||||||
if (! hist) {
|
if (! hist) {
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,13 @@ struct price_point_t
|
||||||
* Long.
|
* Long.
|
||||||
*/
|
*/
|
||||||
class commodity_t
|
class commodity_t
|
||||||
: public delegates_flags<>,
|
: public delegates_flags<uint_least16_t>,
|
||||||
public equality_comparable1<commodity_t, noncopyable>
|
public equality_comparable1<commodity_t, noncopyable>
|
||||||
{
|
{
|
||||||
friend class commodity_pool_t;
|
friend class commodity_pool_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class base_t : public noncopyable, public supports_flags<>
|
class base_t : public noncopyable, public supports_flags<uint_least16_t>
|
||||||
{
|
{
|
||||||
base_t();
|
base_t();
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ public:
|
||||||
history_map prices;
|
history_map prices;
|
||||||
ptime last_lookup;
|
ptime last_lookup;
|
||||||
|
|
||||||
void add_price(const commodity_t& source,
|
void add_price(commodity_t& source,
|
||||||
const datetime_t& date,
|
const datetime_t& date,
|
||||||
const amount_t& price,
|
const amount_t& price,
|
||||||
const bool reflexive = true);
|
const bool reflexive = true);
|
||||||
|
|
@ -111,14 +111,14 @@ public:
|
||||||
{
|
{
|
||||||
history_by_commodity_map histories;
|
history_by_commodity_map histories;
|
||||||
|
|
||||||
void add_price(const commodity_t& source,
|
void add_price(commodity_t& source,
|
||||||
const datetime_t& date,
|
const datetime_t& date,
|
||||||
const amount_t& price,
|
const amount_t& price,
|
||||||
const bool reflexive = true);
|
const bool reflexive = true);
|
||||||
bool remove_price(const datetime_t& date, commodity_t& commodity);
|
bool remove_price(const datetime_t& date, commodity_t& commodity);
|
||||||
|
|
||||||
optional<price_point_t>
|
optional<price_point_t>
|
||||||
find_price(const commodity_t& source,
|
find_price(const commodity_t& source,
|
||||||
const optional<commodity_t&>& commodity = none,
|
const optional<commodity_t&>& commodity = none,
|
||||||
const optional<datetime_t>& moment = none,
|
const optional<datetime_t>& moment = none,
|
||||||
const optional<datetime_t>& oldest = none
|
const optional<datetime_t>& oldest = none
|
||||||
|
|
@ -127,7 +127,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
) const;
|
) const;
|
||||||
optional<price_point_t>
|
optional<price_point_t>
|
||||||
find_price(const commodity_t& source,
|
find_price(const commodity_t& source,
|
||||||
const std::vector<commodity_t *>& commodities,
|
const std::vector<commodity_t *>& commodities,
|
||||||
const optional<datetime_t>& moment = none,
|
const optional<datetime_t>& moment = none,
|
||||||
const optional<datetime_t>& oldest = none
|
const optional<datetime_t>& oldest = none
|
||||||
|
|
@ -142,15 +142,16 @@ public:
|
||||||
history(const std::vector<commodity_t *>& commodities);
|
history(const std::vector<commodity_t *>& commodities);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMODITY_STYLE_DEFAULTS 0x00
|
#define COMMODITY_STYLE_DEFAULTS 0x000
|
||||||
#define COMMODITY_STYLE_SUFFIXED 0x01
|
#define COMMODITY_STYLE_SUFFIXED 0x001
|
||||||
#define COMMODITY_STYLE_SEPARATED 0x02
|
#define COMMODITY_STYLE_SEPARATED 0x002
|
||||||
#define COMMODITY_STYLE_EUROPEAN 0x04
|
#define COMMODITY_STYLE_EUROPEAN 0x004
|
||||||
#define COMMODITY_STYLE_THOUSANDS 0x08
|
#define COMMODITY_STYLE_THOUSANDS 0x008
|
||||||
#define COMMODITY_NOMARKET 0x10
|
#define COMMODITY_NOMARKET 0x010
|
||||||
#define COMMODITY_BUILTIN 0x20
|
#define COMMODITY_BUILTIN 0x020
|
||||||
#define COMMODITY_WALKED 0x40
|
#define COMMODITY_WALKED 0x040
|
||||||
#define COMMODITY_KNOWN 0x80
|
#define COMMODITY_KNOWN 0x080
|
||||||
|
#define COMMODITY_PRIMARY 0x100
|
||||||
|
|
||||||
string symbol;
|
string symbol;
|
||||||
amount_t::precision_t precision;
|
amount_t::precision_t precision;
|
||||||
|
|
@ -164,7 +165,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit base_t(const string& _symbol)
|
explicit base_t(const string& _symbol)
|
||||||
: supports_flags<>(COMMODITY_STYLE_DEFAULTS),
|
: supports_flags<uint_least16_t>(COMMODITY_STYLE_DEFAULTS),
|
||||||
symbol(_symbol), precision(0), searched(false) {
|
symbol(_symbol), precision(0), searched(false) {
|
||||||
TRACE_CTOR(base_t, "const string&");
|
TRACE_CTOR(base_t, "const string&");
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +192,7 @@ public:
|
||||||
public:
|
public:
|
||||||
explicit commodity_t(commodity_pool_t * _parent,
|
explicit commodity_t(commodity_pool_t * _parent,
|
||||||
const shared_ptr<base_t>& _base)
|
const shared_ptr<base_t>& _base)
|
||||||
: delegates_flags<>(*_base.get()), base(_base),
|
: delegates_flags<uint_least16_t>(*_base.get()), base(_base),
|
||||||
parent_(_parent), annotated(false) {
|
parent_(_parent), annotated(false) {
|
||||||
TRACE_CTOR(commodity_t, "");
|
TRACE_CTOR(commodity_t, "");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,22 +120,23 @@ value_t report_t::fn_display_total(call_scope_t& scope)
|
||||||
return HANDLER(display_total_).expr.calc(scope);
|
return HANDLER(display_total_).expr.calc(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t report_t::fn_market_value(call_scope_t& args)
|
value_t report_t::fn_market_value(call_scope_t& scope)
|
||||||
{
|
{
|
||||||
interactive_t env(args, "a&ts");
|
interactive_t args(scope, "a&ts");
|
||||||
|
|
||||||
commodity_t * commodity = NULL;
|
commodity_t * commodity = NULL;
|
||||||
if (env.has(2))
|
if (args.has(2))
|
||||||
commodity = amount_t::current_pool->find_or_create(env.get<string>(2));
|
commodity = amount_t::current_pool->find_or_create(args.get<string>(2));
|
||||||
|
|
||||||
DEBUG("report.market", "getting market value of: " << env.value_at(0));
|
DEBUG("report.market", "getting market value of: " << args.value_at(0));
|
||||||
|
|
||||||
value_t result =
|
value_t result =
|
||||||
env.value_at(0).value(env.has(1) ?
|
args.value_at(0).value(! args.has(2),
|
||||||
env.get<datetime_t>(1) : optional<datetime_t>(),
|
args.has(1) ?
|
||||||
commodity ?
|
args.get<datetime_t>(1) : optional<datetime_t>(),
|
||||||
optional<commodity_t&>(*commodity) :
|
commodity ?
|
||||||
optional<commodity_t&>());
|
optional<commodity_t&>(*commodity) :
|
||||||
|
optional<commodity_t&>());
|
||||||
|
|
||||||
DEBUG("report.market", "result is: " << result);
|
DEBUG("report.market", "result is: " << result);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -165,13 +166,13 @@ value_t report_t::fn_quantity(call_scope_t& args)
|
||||||
return args[0].to_amount().number();
|
return args[0].to_amount().number();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t report_t::fn_truncate(call_scope_t& args)
|
value_t report_t::fn_truncate(call_scope_t& scope)
|
||||||
{
|
{
|
||||||
interactive_t env(args, "v&ll");
|
interactive_t args(scope, "v&ll");
|
||||||
return string_value(format_t::truncate
|
return string_value(format_t::truncate
|
||||||
(env.get<string>(0),
|
(args.get<string>(0),
|
||||||
env.has(1) && env.get<long>(1) > 0 ? env.get<long>(1) : 0,
|
args.has(1) && args.get<long>(1) > 0 ? args.get<long>(1) : 0,
|
||||||
env.has(2) ? env.get<long>(2) : -1));
|
args.has(2) ? args.get<long>(2) : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t report_t::fn_justify(call_scope_t& scope)
|
value_t report_t::fn_justify(call_scope_t& scope)
|
||||||
|
|
@ -400,6 +401,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
|
||||||
else OPT_(end_);
|
else OPT_(end_);
|
||||||
else OPT(equity);
|
else OPT(equity);
|
||||||
else OPT(exact);
|
else OPT(exact);
|
||||||
|
else OPT(exchange_);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
OPT(flat);
|
OPT(flat);
|
||||||
|
|
@ -498,7 +500,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
|
||||||
else OPT_(wide);
|
else OPT_(wide);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
OPT_CH(comm_as_payee);
|
OPT_CH(exchange_);
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
OPT_CH(date_format_);
|
OPT_CH(date_format_);
|
||||||
|
|
|
||||||
20
src/report.h
20
src/report.h
|
|
@ -269,7 +269,7 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, code_as_payee);
|
OPTION(report_t, code_as_payee);
|
||||||
OPTION(report_t, comm_as_payee); // -x
|
OPTION(report_t, comm_as_payee);
|
||||||
OPTION(report_t, code_as_account);
|
OPTION(report_t, code_as_account);
|
||||||
OPTION(report_t, comm_as_account);
|
OPTION(report_t, comm_as_account);
|
||||||
OPTION(report_t, color);
|
OPTION(report_t, color);
|
||||||
|
|
@ -374,6 +374,14 @@ public:
|
||||||
|
|
||||||
OPTION(report_t, equity);
|
OPTION(report_t, equity);
|
||||||
OPTION(report_t, exact);
|
OPTION(report_t, exact);
|
||||||
|
|
||||||
|
OPTION_(report_t, exchange_, DO_(args) { // -x
|
||||||
|
on_with(args[0]);
|
||||||
|
call_scope_t no_args(*parent);
|
||||||
|
parent->HANDLER(market).parent = parent;
|
||||||
|
parent->HANDLER(market).handler(no_args);
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, flat);
|
OPTION(report_t, flat);
|
||||||
OPTION(report_t, forecast_while_);
|
OPTION(report_t, forecast_while_);
|
||||||
OPTION(report_t, format_); // -F
|
OPTION(report_t, format_); // -F
|
||||||
|
|
@ -402,8 +410,10 @@ public:
|
||||||
|
|
||||||
OPTION_(report_t, market, DO() { // -V
|
OPTION_(report_t, market, DO() { // -V
|
||||||
parent->HANDLER(revalued).on_only();
|
parent->HANDLER(revalued).on_only();
|
||||||
parent->HANDLER(display_amount_).set_expr("market(amount_expr)");
|
parent->HANDLER(display_amount_)
|
||||||
parent->HANDLER(display_total_).set_expr("market(total_expr)");
|
.set_expr("exchange ? market(amount_expr, now, exchange) : market(amount_expr)");
|
||||||
|
parent->HANDLER(display_total_)
|
||||||
|
.set_expr("exchange ? market(total_expr, now, exchange) : market(total_expr)");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, monthly, DO() { // -M
|
OPTION_(report_t, monthly, DO() { // -M
|
||||||
|
|
@ -447,11 +457,11 @@ public:
|
||||||
OPTION(report_t, period_sort_);
|
OPTION(report_t, period_sort_);
|
||||||
|
|
||||||
OPTION__(report_t, plot_amount_format_, CTOR(report_t, plot_amount_format_) {
|
OPTION__(report_t, plot_amount_format_, CTOR(report_t, plot_amount_format_) {
|
||||||
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(amount)))\n");
|
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, plot_total_format_, CTOR(report_t, plot_total_format_) {
|
OPTION__(report_t, plot_total_format_, CTOR(report_t, plot_total_format_) {
|
||||||
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(total)))\n");
|
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, price, DO() { // -I
|
OPTION_(report_t, price, DO() { // -I
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,11 @@ expr_t::ptr_op_t session_t::lookup(const string& name)
|
||||||
{
|
{
|
||||||
const char * p = name.c_str();
|
const char * p = name.c_str();
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
|
case 'n':
|
||||||
|
if (is_eq(p, "now"))
|
||||||
|
return MAKE_FUNCTOR(session_t::fn_now);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
if (WANT_OPT()) { p += OPT_PREFIX_LEN;
|
if (WANT_OPT()) { p += OPT_PREFIX_LEN;
|
||||||
if (option_t<session_t> * handler = lookup_option(p))
|
if (option_t<session_t> * handler = lookup_option(p))
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ public:
|
||||||
clean_accounts();
|
clean_accounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t fn_now(call_scope_t&) {
|
||||||
|
return CURRENT_TIME();
|
||||||
|
}
|
||||||
value_t fn_today(call_scope_t&) {
|
value_t fn_today(call_scope_t&) {
|
||||||
return CURRENT_DATE();
|
return CURRENT_DATE();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
src/value.cc
20
src/value.cc
|
|
@ -1137,23 +1137,25 @@ bool value_t::is_zero() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t value_t::value(const optional<datetime_t>& moment,
|
value_t value_t::value(const bool primary_only,
|
||||||
|
const optional<datetime_t>& moment,
|
||||||
const optional<commodity_t&>& in_terms_of) const
|
const optional<commodity_t&>& in_terms_of) const
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
case AMOUNT: {
|
case AMOUNT:
|
||||||
if (optional<amount_t> val = as_amount().value(moment, in_terms_of))
|
if (optional<amount_t> val =
|
||||||
|
as_amount().value(primary_only, moment, in_terms_of))
|
||||||
return *val;
|
return *val;
|
||||||
return false;
|
return *this;
|
||||||
}
|
|
||||||
case BALANCE: {
|
case BALANCE:
|
||||||
if (optional<balance_t> bal = as_balance().value(moment, in_terms_of))
|
if (optional<balance_t> bal =
|
||||||
|
as_balance().value(primary_only, moment, in_terms_of))
|
||||||
return *bal;
|
return *bal;
|
||||||
return false;
|
return *this;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -427,8 +427,9 @@ public:
|
||||||
void in_place_unreduce(); // exists for efficiency's sake
|
void in_place_unreduce(); // exists for efficiency's sake
|
||||||
|
|
||||||
// Return the "market value" of a given value at a specific time.
|
// Return the "market value" of a given value at a specific time.
|
||||||
value_t value(const optional<datetime_t>& moment = none,
|
value_t value(const bool primary_only = false,
|
||||||
const optional<commodity_t&>& in_terms_of = none) const;
|
const optional<datetime_t>& moment = none,
|
||||||
|
const optional<commodity_t&>& in_terms_of = none) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truth tests.
|
* Truth tests.
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,10 @@ namespace {
|
||||||
return string_value(xact.amount.commodity().symbol());
|
return string_value(xact.amount.commodity().symbol());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t get_commodity_is_primary(xact_t& xact) {
|
||||||
|
return xact.amount.commodity().has_flags(COMMODITY_PRIMARY);
|
||||||
|
}
|
||||||
|
|
||||||
value_t get_cost(xact_t& xact) {
|
value_t get_cost(xact_t& xact) {
|
||||||
if (xact.has_xdata() &&
|
if (xact.has_xdata() &&
|
||||||
xact.xdata().has_flags(XACT_EXT_COMPOUND)) {
|
xact.xdata().has_flags(XACT_EXT_COMPOUND)) {
|
||||||
|
|
@ -262,6 +266,8 @@ expr_t::ptr_op_t xact_t::lookup(const string& name)
|
||||||
case 'p':
|
case 'p':
|
||||||
if (name == "payee")
|
if (name == "payee")
|
||||||
return WRAP_FUNCTOR(get_wrapper<&get_payee>);
|
return WRAP_FUNCTOR(get_wrapper<&get_payee>);
|
||||||
|
else if (name == "primary")
|
||||||
|
return WRAP_FUNCTOR(get_wrapper<&get_commodity_is_primary>);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
|
|
||||||
|
|
@ -68,11 +68,11 @@ void CommodityTestCase::testPriceHistory()
|
||||||
cad.add_price(jan17_06, amount_t("$1.11"));
|
cad.add_price(jan17_06, amount_t("$1.11"));
|
||||||
|
|
||||||
#ifndef NOT_FOR_PYTHON
|
#ifndef NOT_FOR_PYTHON
|
||||||
optional<amount_t> amt = x1.value(feb28_07sbm);
|
optional<amount_t> amt = x1.value(false, feb28_07sbm);
|
||||||
assertTrue(amt);
|
assertTrue(amt);
|
||||||
assertEqual(amount_t("$1831.83"), *amt);
|
assertEqual(amount_t("$1831.83"), *amt);
|
||||||
|
|
||||||
amt = x1.value(CURRENT_TIME());
|
amt = x1.value(false, CURRENT_TIME());
|
||||||
assertTrue(amt);
|
assertTrue(amt);
|
||||||
assertEqual(string("$2124.12"), amt->to_string());
|
assertEqual(string("$2124.12"), amt->to_string());
|
||||||
#ifdef INTEGER_MATH
|
#ifdef INTEGER_MATH
|
||||||
|
|
@ -81,18 +81,18 @@ void CommodityTestCase::testPriceHistory()
|
||||||
assertEqual(string("$2124.1220"), amt->to_fullstring());
|
assertEqual(string("$2124.1220"), amt->to_fullstring());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
amt = x1.value(CURRENT_TIME(), euro);
|
amt = x1.value(false, CURRENT_TIME(), euro);
|
||||||
assertTrue(amt);
|
assertTrue(amt);
|
||||||
assertEqual(string("EUR 1366.87"), amt->rounded().to_string());
|
assertEqual(string("EUR 1366.87"), amt->rounded().to_string());
|
||||||
|
|
||||||
// Add a newer Euro pricing
|
// Add a newer Euro pricing
|
||||||
aapl.add_price(jan17_07, amount_t("EUR 23.00"));
|
aapl.add_price(jan17_07, amount_t("EUR 23.00"));
|
||||||
|
|
||||||
amt = x1.value(CURRENT_TIME(), euro);
|
amt = x1.value(false, CURRENT_TIME(), euro);
|
||||||
assertTrue(amt);
|
assertTrue(amt);
|
||||||
assertEqual(string("EUR 2302.30"), amt->to_string());
|
assertEqual(string("EUR 2302.30"), amt->to_string());
|
||||||
|
|
||||||
amt = x1.value(CURRENT_TIME(), cad);
|
amt = x1.value(false, CURRENT_TIME(), cad);
|
||||||
assertTrue(amt);
|
assertTrue(amt);
|
||||||
assertEqual(string("CAD 3223.22"), amt->to_string());
|
assertEqual(string("CAD 3223.22"), amt->to_string());
|
||||||
#endif // NOT_FOR_PYTHON
|
#endif // NOT_FOR_PYTHON
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue