+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 a price
+offer changed.
+
+Price sources put that together by making some compromises:
+
+=over 4
+
+=item 1.
+
+Only change the price on creation of a position or when asked to.
+
+=item 2.
+
+Either set the price from a price source and let it be read only, or use a free
+price.
+
+=item 3.
+
+Save the origin of each price with the record so that the calculation can be
+reproduced.
+
+=item 4.
+
+Make price calculation flexible and pluggable.
+
+=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. The fourth point ensures that
+insular calculation processes can be developed independent of the core code.
+
+=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>