diff options
-rw-r--r-- | src/amount.cc | 16 | ||||
-rw-r--r-- | src/amount.h | 2 | ||||
-rw-r--r-- | src/balance.cc | 10 | ||||
-rw-r--r-- | src/balance.h | 2 | ||||
-rw-r--r-- | src/report.cc | 16 | ||||
-rw-r--r-- | src/report.h | 7 | ||||
-rw-r--r-- | src/value.cc | 12 | ||||
-rw-r--r-- | src/value.h | 2 | ||||
-rw-r--r-- | test/baseline/opt-price.test | 47 |
9 files changed, 107 insertions, 7 deletions
diff --git a/src/amount.cc b/src/amount.cc index 0b798686..2434f110 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -576,6 +576,17 @@ amount_t::value(const bool primary_only, return none; } +amount_t amount_t::price() const +{ + if (is_annotated() && annotation().price) { + amount_t temp(*annotation().price); + temp *= *this; + DEBUG("amount.price", "Returning price of " << *this << " = " << temp); + return temp; + } + return *this; +} + int amount_t::sign() const { @@ -784,8 +795,9 @@ bool amount_t::is_annotated() const throw_(amount_error, _("Cannot determine if an uninitialized amount's commodity is annotated")); - assert(! commodity().annotated || as_annotated_commodity(commodity()).details); - return commodity().annotated; + assert(! has_commodity() || ! commodity().annotated || + as_annotated_commodity(commodity()).details); + return has_commodity() && commodity().annotated; } annotation_t& amount_t::annotation() diff --git a/src/amount.h b/src/amount.h index 990b326f..b3c632af 100644 --- a/src/amount.h +++ b/src/amount.h @@ -384,6 +384,8 @@ public: const optional<datetime_t>& moment = none, const optional<commodity_t&>& in_terms_of = none) const; + amount_t price() const; + /*@}*/ /** @name Truth tests diff --git a/src/balance.cc b/src/balance.cc index 07657287..274f860a 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -203,6 +203,16 @@ balance_t::value(const bool primary_only, return resolved ? temp : optional<balance_t>(); } +balance_t balance_t::price() const +{ + balance_t temp; + + foreach (const amounts_map::value_type& pair, amounts) + temp += pair.second.price(); + + return temp; +} + optional<amount_t> balance_t::commodity_amount(const optional<const commodity_t&>& commodity) const { diff --git a/src/balance.h b/src/balance.h index 142621f8..765c46dd 100644 --- a/src/balance.h +++ b/src/balance.h @@ -367,6 +367,8 @@ public: const optional<datetime_t>& moment = none, const optional<commodity_t&>& in_terms_of = none) const; + balance_t price() const; + /** * Truth tests. An balance may be truth test in two ways: * diff --git a/src/report.cc b/src/report.cc index 3e38aef2..4c8a40e6 100644 --- a/src/report.cc +++ b/src/report.cc @@ -246,16 +246,18 @@ value_t report_t::fn_quoted(call_scope_t& args) return string_value(out.str()); } -value_t report_t::fn_join(call_scope_t& args) +value_t report_t::fn_join(call_scope_t& scope) { + interactive_t args(scope, "s"); + std::ostringstream out; - foreach (const char ch, args[0].to_string()) + foreach (const char ch, args.get<string>(0)) { if (ch != '\n') out << ch; else out << "\\n"; - + } return string_value(out.str()); } @@ -299,6 +301,12 @@ value_t report_t::fn_percent(call_scope_t& scope) (args.get<amount_t>(0) / args.get<amount_t>(1)).number()); } +value_t report_t::fn_price(call_scope_t& scope) +{ + interactive_t args(scope, "v"); + return args.value_at(0).price(); +} + namespace { value_t fn_black(call_scope_t&) { return string_value("black"); @@ -846,6 +854,8 @@ expr_t::ptr_op_t report_t::lookup(const string& name) return WRAP_FUNCTOR(fn_false); else if (is_eq(p, "percent")) return MAKE_FUNCTOR(report_t::fn_percent); + else if (is_eq(p, "price")) + return MAKE_FUNCTOR(report_t::fn_price); break; case 'q': diff --git a/src/report.h b/src/report.h index 6f442b5d..71dc4ca2 100644 --- a/src/report.h +++ b/src/report.h @@ -158,6 +158,7 @@ public: value_t fn_format_date(call_scope_t& scope); value_t fn_ansify_if(call_scope_t& scope); value_t fn_percent(call_scope_t& scope); + value_t fn_price(call_scope_t& scope); value_t fn_now(call_scope_t&) { return terminus; @@ -613,8 +614,10 @@ public: }); OPTION_(report_t, price, DO() { // -I - parent->HANDLER(revalued).off(); - parent->HANDLER(amount_).set_expr(string("--price"), "price"); + parent->HANDLER(display_amount_) + .set_expr(string("--price"), "price(amount_expr)"); + parent->HANDLER(display_total_) + .set_expr(string("--price"), "price(total_expr)"); }); OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) { diff --git a/src/value.cc b/src/value.cc index 54d4bfc2..b19ad956 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1230,6 +1230,18 @@ value_t value_t::value(const bool primary_only, return NULL_VALUE; } +value_t value_t::price() const +{ + switch (type()) { + case AMOUNT: + return as_amount().price(); + case BALANCE: + return as_balance().price(); + default: + return *this; + } +} + value_t value_t::exchange_commodities(const std::string& commodities, const bool add_prices, const optional<datetime_t>& moment) diff --git a/src/value.h b/src/value.h index 31ed1d58..62943e62 100644 --- a/src/value.h +++ b/src/value.h @@ -449,6 +449,8 @@ public: const optional<datetime_t>& moment = none, const optional<commodity_t&>& in_terms_of = none) const; + value_t price() const; + value_t exchange_commodities(const std::string& commodities, const bool add_prices = false, const optional<datetime_t>& moment = none); diff --git a/test/baseline/opt-price.test b/test/baseline/opt-price.test new file mode 100644 index 00000000..06cc7751 --- /dev/null +++ b/test/baseline/opt-price.test @@ -0,0 +1,47 @@ +reg equities +<<< +2008/01/01 * Purchase Apple shares + Equities 1000 AAPL @ $2 + Cash $-2000 + +2008/06/30 * Sell some Apple shares + Cash $1250 + Equities -500 AAPL {$2} @ $2.50 + Income:Gains $-250 + +P 2008/10/01 02:18:02 AAPL $3 +P 2009/01/31 02:18:02 AAPL $4 +P 3000/01/01 02:18:02 APPL $100 +>>>1 +08-Jan-01 Purchase Apple shares Equities 1000 AAPL 1000 AAPL +08-Jun-30 Sell some Apple sha.. Equities -500 AAPL 500 AAPL +>>>2 +=== 0 +reg -B equities +>>>1 +08-Jan-01 Purchase Apple shares Equities $2000 $2000 +08-Jun-30 Sell some Apple sha.. Equities $-1250 $750 +>>>2 +=== 0 +reg --end 2009/06/26 -V equities +>>>1 +08-Jan-01 Purchase Apple shares Equities $2000 $2000 +08-Jun-30 Commodities revalued <Revalued> $500 $2500 +08-Jun-30 Sell some Apple sha.. Equities $-1250 $1250 +09-Jun-26 Commodities revalued <Revalued> $750 $2000 +>>>2 +=== 0 +reg --end 2009/06/26 -G equities +>>>1 +08-Jan-01 Purchase Apple shares Equities 0 0 +08-Jun-30 Commodities revalued <Revalued> $500 $500 +08-Jun-30 Sell some Apple sha.. Equities 0 $500 +09-Jun-26 Commodities revalued <Revalued> $750 $1250 +>>>2 +=== 0 +reg -I equities +>>>1 +08-Jan-01 Purchase Apple shares Equities $2000 $2000 +08-Jun-30 Sell some Apple sha.. Equities $-1000 $1000 +>>>2 +=== 0 |