diff options
author | John Wiegley <johnw@newartisans.com> | 2008-07-24 11:36:40 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-07-24 11:36:40 -0400 |
commit | ee396957226e2273bc60ede7192c27038c432f24 (patch) | |
tree | e87839dd6949461f5e3c9fb34071e7cea412b761 /commodity.cc | |
parent | 171f79dda268b59d708f5002d1d616a71a30ecb5 (diff) | |
download | fork-ledger-ee396957226e2273bc60ede7192c27038c432f24.tar.gz fork-ledger-ee396957226e2273bc60ede7192c27038c432f24.tar.bz2 fork-ledger-ee396957226e2273bc60ede7192c27038c432f24.zip |
Parsing now works again. And there was much rejoicing.
Diffstat (limited to 'commodity.cc')
-rw-r--r-- | commodity.cc | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/commodity.cc b/commodity.cc index 3bb3ec72..37c4fab9 100644 --- a/commodity.cc +++ b/commodity.cc @@ -118,6 +118,75 @@ optional<amount_t> commodity_t::value(const optional<datetime_t>& moment) return price; } +amount_t commodity_t::exchange(const amount_t& amount, + amount_t& final_cost, // out + amount_t& basis_cost, // out + const optional<amount_t>& total_cost_, + const optional<amount_t>& per_unit_cost_, + const optional<datetime_t>& moment, + const optional<string>& tag) +{ + // (assert (or (and total-cost (not per-unit-cost)) + // (and per-unit-cost (not total-cost)))) + + assert((total_cost_ && ! per_unit_cost_) || (per_unit_cost_ && ! total_cost_)); + + // (let* ((commodity (amount-commodity amount)) + // (current-annotation + // (and (annotated-commodity-p commodity) + // (commodity-annotation commodity))) + // (base-commodity (if (annotated-commodity-p commodity) + // (get-referent commodity) + // commodity)) + // (per-unit-cost (or per-unit-cost + // (divide total-cost amount))) + // (total-cost (or total-cost + // (multiply per-unit-cost amount)))) + + commodity_t& commodity(amount.commodity()); + + annotation_t * current_annotation = NULL; + if (commodity.annotated) + current_annotation = &as_annotated_commodity(commodity).details; + + commodity_t& base_commodity + (current_annotation ? + as_annotated_commodity(commodity).referent() : commodity); + + amount_t per_unit_cost(per_unit_cost_ ? + *per_unit_cost_ : *total_cost_ / amount); + final_cost = total_cost_ ? *total_cost_ : *per_unit_cost_ * amount; + + // Add a price history entry for this conversion if we know when it took + // place + + // (if (and moment (not (commodity-no-market-price-p base-commodity))) + // (add-price base-commodity per-unit-cost moment)) + + if (moment && ! commodity.has_flags(COMMODITY_STYLE_NOMARKET)) + base_commodity.add_price(*moment, per_unit_cost); + + // ;; returns: ANNOTATED-AMOUNT TOTAL-COST BASIS-COST + // (values (annotate-commodity + // amount + // (make-commodity-annotation :price per-unit-cost + // :date moment + // :tag tag)) + // total-cost + // (if current-annotation + // (multiply (annotation-price current-annotation) amount) + // total-cost)))) + + if (current_annotation && current_annotation->price) + basis_cost = *current_annotation->price * amount; + else + basis_cost = final_cost; + + amount_t ann_amount(amount); + ann_amount.annotate_commodity(annotation_t(per_unit_cost, moment, tag)); + return ann_amount; +} + commodity_t::operator bool() const { return this != parent().null_commodity; |