summaryrefslogtreecommitdiff
path: root/src/amount.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/amount.cc')
-rw-r--r--src/amount.cc50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/amount.cc b/src/amount.cc
index 7c9a6931..2434f110 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -33,6 +33,8 @@
#include "amount.h"
#include "commodity.h"
+#include "annotate.h"
+#include "pool.h"
namespace ledger {
@@ -343,8 +345,8 @@ amount_t& amount_t::operator*=(const amount_t& amt)
_dup();
mpq_mul(MP(quantity), MP(quantity), MP(amt.quantity));
- quantity->prec = static_cast<precision_t>(quantity->prec +
- amt.quantity->prec);
+ quantity->prec =
+ static_cast<precision_t>(quantity->prec + amt.quantity->prec);
if (! has_commodity())
commodity_ = amt.commodity_;
@@ -382,7 +384,7 @@ amount_t& amount_t::operator/=(const amount_t& amt)
mpq_div(MP(quantity), MP(quantity), MP(amt.quantity));
quantity->prec =
static_cast<precision_t>(quantity->prec + amt.quantity->prec +
- quantity->prec + extend_by_digits);
+ extend_by_digits);
if (! has_commodity())
commodity_ = amt.commodity_;
@@ -488,7 +490,10 @@ void amount_t::in_place_unround()
return;
_dup();
+
+ DEBUG("amount.unround", "Unrounding " << *this);
set_keep_precision(true);
+ DEBUG("amount.unround", "Unrounded = " << *this);
}
void amount_t::in_place_reduce()
@@ -551,17 +556,37 @@ amount_t::value(const bool primary_only,
annotation().has_flags(ANNOTATION_PRICE_FIXATED)) {
return (*annotation().price * number()).rounded();
}
- else if (optional<price_point_t> point =
- commodity().find_price(in_terms_of, moment)) {
- return (point->price * number()).rounded();
+ else {
+ optional<price_point_t> point =
+ commodity().find_price(in_terms_of, moment);
+
+ // Whether a price was found or not, check whether we should attempt
+ // to download a price from the Internet. This is done if (a) no
+ // price was found, or (b) the price is "stale" according to the
+ // setting of --price-exp.
+ point = commodity().check_for_updated_price(point, moment, in_terms_of);
+ if (point)
+ return (point->price * number()).rounded();
}
}
} else {
- throw_(amount_error, _("Cannot determine value of an uninitialized amount"));
+ throw_(amount_error,
+ _("Cannot determine value of an uninitialized amount"));
}
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
{
@@ -740,7 +765,7 @@ void amount_t::annotate(const annotation_t& details)
if (! quantity)
throw_(amount_error, _("Cannot annotate the commodity of an uninitialized amount"));
else if (! has_commodity())
- throw_(amount_error, _("Cannot annotate an amount with no commodity"));
+ return; // ignore attempt to annotate a "bare commodity
if (commodity().annotated) {
this_ann = &as_annotated_commodity(commodity());
@@ -770,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()
@@ -1062,8 +1088,10 @@ void amount_t::print(std::ostream& _out) const
bool amount_t::valid() const
{
if (quantity) {
- if (! quantity->valid())
+ if (! quantity->valid()) {
+ DEBUG("ledger.validate", "amount_t: ! quantity->valid()");
return false;
+ }
if (quantity->ref == 0) {
DEBUG("ledger.validate", "amount_t: quantity->ref == 0");