+The result was that the price of an item in a record seemed to change on a
+whim, and the origin of the price itself being opaque.
+
+Unrelated to that, users asked for more ways to store special prices, based on
+qty (block pricing, bulk discount), based on date (special offers), based on
+customers (special terms), up to full blown calculation modules.
+
+On a third front sales personnel asked for ways to see what price options a
+position in a quotation has, and wanted information available when prices
+changed to make better informed choices about sales later in the workflow.
+
+Price sources now extend the previous pricing by attaching a source to every
+price in records. The information it provides are:
+
+=over 4
+
+=item 1.
+
+Where did this price originate?
+
+=item 2.
+
+If this price would be calculated today, is it still the same as it was when
+this record was created?
+
+=item 3.
+
+If I want to price an item in this record now, which prices are available?
+
+=item 4.
+
+Which one is the "best"?
+
+=back
+
+=head1 GUARANTEES
+
+To ensure price source prices are comprehensible and reproducible, some
+invariants are guaranteed:
+
+=over 4
+
+=item 1.
+
+Price sources will never on their own change a price. They will offer options,
+and it is up to the user to change a price.
+
+=item 2.
+
+If a price is set from a source, it is read only. A price edited manually is by
+definition not a sourced price.
+
+=item 3.
+
+A price should be able to repeat the calculations done to arrive at the price
+when it was first used. If these calculations are no longer applicable (special
+offer expired) this should be signalled. If the calculations result in a
+different price, this should be signalled. If the calculations fail (needed
+information is no longer present) this must be signalled.
+
+=back
+
+The first point creates user security by never changing a price for them
+without their explicit consent, eliminating all problems originating from
+trying to be smart. The second and third one ensure that later on the
+calculation can be repeated so that invalid prices can be caught (because for
+example the special offer is no longer valid), and so that sales personnel have
+information about rising or falling prices.
+
+=head1 STRUCTURE
+
+Price sources are managed by this package (L<SL::PriceSource>), and all
+external access should be by using it's interface.
+
+Each source is an instance of L<SL::PriceSource::Base> and the available
+implementations are recorded in L<SL::PriceSource::ALL>. Prices and discounts
+returned by interface methods are instances of L<SL::PriceSource::Price> and
+L<SL::PriceSource::Discout>.
+
+Returned prices and discounts should be checked for entries in C<invalid> and
+C<missing>, see documentation in their classes.
+
+=head1 INTERFACE METHODS
+
+=over 4
+
+=item C<new PARAMS>
+
+C<PARAMS> must contain both C<record> and C<record_item>. C<record_item> does
+not have to be registered in C<record>.
+
+=item C<price_from_source>
+
+Attempts to retrieve a formerly calculated price with the same conditions
+
+=item C<discount_from_source>
+
+Attempts to retrieve a formerly calculated discount with the same conditions
+
+=item C<available_prices>
+
+Returns all available prices.
+
+=item C<available_discounts>
+
+Returns all available discounts.
+
+=item C<best_price>
+
+Attempts to get the best available price. returns L<empty_price> if no price is found.
+
+=item C<best_discount>
+
+Attempts to get the best available discount. returns L<empty_discount> if no discount is found.
+
+=item C<empty_price>
+
+A special empty price, that does not change the previously entered price, and
+opens the price field to manual changes.
+
+=item C<empty_discount>
+
+A special empty discount, that does not change the previously entered discount, and
+opens the discount field to manual changes.
+
+=back
+
+=head1 SEE ALSO
+
+L<SL::PriceSource::Base>,
+L<SL::PriceSource::Price>,
+L<SL::PriceSource::Discount>,
+L<SL::PriceSource::ALL>
+
+=head1 BUGS AND CAVEATS
+
+=over 4
+
+=item *
+
+The current model of price sources requires a record and a record_item for
+every price calculation. This means that price structures can never be used
+when no record is available, such as calculation the worth of assembly rows.
+
+A possible solution is to either split price sources into simple and complex
+ones (where the former do not require records).
+
+Another would be to have default values for the input normally taken from
+records (like qty defaulting to 1).
+
+A last one would be to provide an alternative input channel for needed
+properties.
+
+=item *
+
+Discount sources were implemented as a copy of the prices with slightly
+different semantics. Need to do a real design. A requirement is, that a single
+source can provide both prices and discounts (needed for price_rules).
+
+=item *
+
+Priorities are implemented ad hoc. The semantics which are chosen by the "best"
+accessors are unintuitive because they do not guarantee anything. Better
+terminology might help.
+
+=item *
+
+It is currently not possible to link a price to the price of the generating
+record_item (i.e. the price of a delivery order item to the order item it was
+generated from). This is crucial to enterprises that calculate all their prices
+in orders, and update those after they made delivery orders.
+
+=item *
+
+Currently it is only possible to provide additional prices, but not to restrict
+prices. Potential scenarios include credit limit customers which do not receive
+benefits from sales, or general ALLOW, DENY order calculation.
+
+=item *
+
+Composing price sources is disallowed for clarity, but all price sources need
+to be aware of units and price_factors. This is madness.
+
+=item *
+
+A common complaint is that prices from certain vendors are always negotiated
+and should use a default value but must be editable (like free prices) by
+default. This should be orthogonal for all prices.