From fc7e67f40368914d74f6cd3521ac2b7faea01280 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 20 Jun 2010 18:02:19 -0400 Subject: Do not record market values for fixated exchanges Do not record commodity exchanges where amount's commodity has a fixated price, since this does not establish a market value for the base commodity. --- src/pool.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/pool.cc') diff --git a/src/pool.cc b/src/pool.cc index 618a43c5..df20d179 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -254,7 +254,13 @@ commodity_pool_t::exchange(const amount_t& amount, DEBUG("commodity.prices.add", "exchange: per-unit-cost = " << per_unit_cost); - if (! per_unit_cost.is_realzero()) + // Do not record commodity exchanges where amount's commodity has a + // fixated price, since this does not establish a market value for the + // base commodity. + if (! per_unit_cost.is_realzero() && + (current_annotation == NULL || + ! (current_annotation->price && + current_annotation->has_flags(ANNOTATION_PRICE_FIXATED)))) exchange(commodity, per_unit_cost, moment ? *moment : CURRENT_TIME()); cost_breakdown_t breakdown; -- cgit v1.2.3 From 82e43fe125a9b2158976fe5a3afccfa85d7a7574 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 20 Jun 2010 18:54:21 -0400 Subject: If fixated price commodities are mixed, show them For example, if a Ledger file contains transactions with the use of both EUR and EUR {=PRICE}, then regular reports will always show the {=PRICE}, disabling the by-name commodity merging that takes place. In brief, fixated and non-fixated commodities are now non-mergable. If a file contains all of one, or all of the other, they will still be merged, since these separate usages do not conflict the way that fixated and non-fixated together do. --- src/annotate.cc | 50 ++++++++++++++++++++++++++++++++++------------ src/commodity.h | 23 +++++++++++---------- src/pool.cc | 12 +++++++++++ test/regress/C0212EAC.test | 33 ++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 test/regress/C0212EAC.test (limited to 'src/pool.cc') diff --git a/src/annotate.cc b/src/annotate.cc index 08b73443..33c0aebb 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -166,15 +166,27 @@ annotated_commodity_t::strip_annotations(const keep_details_t& what_to_keep) commodity_t * new_comm; - bool keep_price = (what_to_keep.keep_price && - (! what_to_keep.only_actuals || - ! details.has_flags(ANNOTATION_PRICE_CALCULATED))); - bool keep_date = (what_to_keep.keep_date && - (! what_to_keep.only_actuals || - ! details.has_flags(ANNOTATION_DATE_CALCULATED))); - bool keep_tag = (what_to_keep.keep_tag && - (! what_to_keep.only_actuals || - ! details.has_flags(ANNOTATION_TAG_CALCULATED))); + bool keep_price = + ((what_to_keep.keep_price || + (details.has_flags(ANNOTATION_PRICE_FIXATED) && + has_flags(COMMODITY_SAW_ANN_PRICE_FLOAT) && + has_flags(COMMODITY_SAW_ANN_PRICE_FIXATED))) && + (! what_to_keep.only_actuals || + ! details.has_flags(ANNOTATION_PRICE_CALCULATED))); + bool keep_date = + (what_to_keep.keep_date && + (! what_to_keep.only_actuals || + ! details.has_flags(ANNOTATION_DATE_CALCULATED))); + bool keep_tag = + (what_to_keep.keep_tag && + (! what_to_keep.only_actuals || + ! details.has_flags(ANNOTATION_TAG_CALCULATED))); + + DEBUG("commodity.annotated.strip", + "Reducing commodity " << *this << std::endl + << " keep price " << keep_price << " " + << " keep date " << keep_date << " " + << " keep tag " << keep_tag); if ((keep_price && details.price) || (keep_date && details.date) || @@ -184,12 +196,24 @@ annotated_commodity_t::strip_annotations(const keep_details_t& what_to_keep) (referent(), annotation_t(keep_price ? details.price : none, keep_date ? details.date : none, keep_tag ? details.tag : none)); - } else { - new_comm = &referent(); + + // Transfer over any relevant annotation flags, as they still apply. + if (new_comm->annotated) { + annotation_t& new_details(as_annotated_commodity(*new_comm).details); + if (keep_price) + new_details.add_flags(details.flags() & + (ANNOTATION_PRICE_CALCULATED | + ANNOTATION_PRICE_FIXATED)); + if (keep_date) + new_details.add_flags(details.flags() & ANNOTATION_DATE_CALCULATED); + if (keep_tag) + new_details.add_flags(details.flags() & ANNOTATION_TAG_CALCULATED); + } + + return *new_comm; } - assert(new_comm); - return *new_comm; + return referent(); } void annotated_commodity_t::write_annotations diff --git a/src/commodity.h b/src/commodity.h index 24cd5a08..fcd26da0 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -164,16 +164,19 @@ protected: class base_t : public noncopyable, public supports_flags { public: -#define COMMODITY_STYLE_DEFAULTS 0x000 -#define COMMODITY_STYLE_SUFFIXED 0x001 -#define COMMODITY_STYLE_SEPARATED 0x002 -#define COMMODITY_STYLE_DECIMAL_COMMA 0x004 -#define COMMODITY_STYLE_THOUSANDS 0x008 -#define COMMODITY_NOMARKET 0x010 -#define COMMODITY_BUILTIN 0x020 -#define COMMODITY_WALKED 0x040 -#define COMMODITY_KNOWN 0x080 -#define COMMODITY_PRIMARY 0x100 +#define COMMODITY_STYLE_DEFAULTS 0x000 +#define COMMODITY_STYLE_SUFFIXED 0x001 +#define COMMODITY_STYLE_SEPARATED 0x002 +#define COMMODITY_STYLE_DECIMAL_COMMA 0x004 +#define COMMODITY_STYLE_THOUSANDS 0x008 +#define COMMODITY_NOMARKET 0x010 +#define COMMODITY_BUILTIN 0x020 +#define COMMODITY_WALKED 0x040 +#define COMMODITY_KNOWN 0x080 +#define COMMODITY_PRIMARY 0x100 +#define COMMODITY_SAW_ANNOTATED 0x200 +#define COMMODITY_SAW_ANN_PRICE_FLOAT 0x400 +#define COMMODITY_SAW_ANN_PRICE_FIXATED 0x800 string symbol; amount_t::precision_t precision; diff --git a/src/pool.cc b/src/pool.cc index df20d179..20b585dd 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -172,12 +172,21 @@ commodity_pool_t::create(commodity_t& comm, const string& mapping_key) { assert(comm); + assert(! comm.has_annotation()); assert(details); assert(! mapping_key.empty()); std::auto_ptr commodity (new annotated_commodity_t(&comm, details)); + comm.add_flags(COMMODITY_SAW_ANNOTATED); + if (details.price) { + if (details.has_flags(ANNOTATION_PRICE_FIXATED)) + comm.add_flags(COMMODITY_SAW_ANN_PRICE_FIXATED); + else + comm.add_flags(COMMODITY_SAW_ANN_PRICE_FLOAT); + } + commodity->qualified_symbol = comm.symbol(); assert(! commodity->qualified_symbol->empty()); @@ -282,6 +291,9 @@ commodity_pool_t::exchange(const amount_t& amount, moment->date() : optional(), tag); annotation.add_flags(ANNOTATION_PRICE_CALCULATED); + if (current_annotation && + current_annotation->has_flags(ANNOTATION_PRICE_FIXATED)) + annotation.add_flags(ANNOTATION_PRICE_FIXATED); if (moment) annotation.add_flags(ANNOTATION_DATE_CALCULATED); if (tag) diff --git a/test/regress/C0212EAC.test b/test/regress/C0212EAC.test new file mode 100644 index 00000000..da178054 --- /dev/null +++ b/test/regress/C0212EAC.test @@ -0,0 +1,33 @@ +reg +<<< +2007-01-01 Opening balances + Assets:Cash 10.00 EUR + Equity:Opening balances + +2008-01-01 Buy 5.00 GBP + Assets:Cash 5.00 GBP @ 1.4 EUR + Assets:Checking + +2009-01-01 Sell 5.00 GBP for 7.50 EUR that I bought for 7.00 EUR + Assets:Cash -5.00 GBP {=1.4 EUR} @ 1.5 EUR + Assets:Checking 7.50 EUR + Income:Gain + +P 2009-02-01 00:00:00 GBP 1.5 EUR +>>> +07-Jan-01 Opening balances Assets:Cash 10.00 EUR 10.00 EUR + Equit:Opening balances -10.00 EUR 0 +08-Jan-01 Buy 5.00 GBP Assets:Cash 5.00 GBP 5.00 GBP + Assets:Checking -7.00 EUR -7.00 EUR + 5.00 GBP +09-Jan-01 Sell 5.00 GBP for 7.. Assets:Cash -5.00 GBP {=1.40 EUR} -7.00 EUR + 5.00 GBP + -5.00 GBP {=1.40 EUR} + Assets:Checking 7.50 EUR 0.50 EUR + 5.00 GBP + -5.00 GBP {=1.40 EUR} + Income:Gain -0.50 EUR 5.00 GBP + -5.00 GBP {=1.40 EUR} + Equity:Capital Gains 0.50 EUR 0.50 EUR + 5.00 GBP + -5.00 GBP {=1.40 EUR} -- cgit v1.2.3