X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FPriceSource%2FBase.pm;h=b095684cfd1597f458314b2c0b983039085414e3;hb=418f0e7084b02c1c057e4f10b858b6bffc25e354;hp=618512d9486c280fb561961d5fd9e9094a230b4f;hpb=2bdd0bc580210b18c1b76a0d0bd4fc3bd3fceca2;p=kivitendo-erp.git diff --git a/SL/PriceSource/Base.pm b/SL/PriceSource/Base.pm index 618512d94..b095684cf 100644 --- a/SL/PriceSource/Base.pm +++ b/SL/PriceSource/Base.pm @@ -29,40 +29,76 @@ __END__ =head1 NAME -SL::PriceSource::Base - +SL::PriceSource::Base - this is the base class for price source adapters =head1 SYNOPSIS - # in consuming module -# TODO: thats bullshit, theres no need to have this pollute the namespace -# make a manager that handles this + # working example adapter: + package SL::PriceSource::FiveOnEverything; - my @list_of_price_sources = $record_item->price_sources; - for (@list_of_price_sources) { - my $internal_name = $_->name; - my $translated_name = $_->description; - my $price = $_->price; + use parent qw(SL::PriceSource::Base); + + # used as internal identifier + sub name { 'simple' } + + # used in frontend to signal where this comes from + sub description { t8('Simple') } + + my $price = SL::PriceSource::Price->new( + price => 5, + description => t8('Only today 5$ on everything!'), + price_source => $self, + ); + + # give list of prices that this + sub available_prices { + return ($price); } - $record_item->set_active_price_source($price_source) # equivalent to: - $record_item->active_price_source($price_source->name); - $record_item->sellprice($price_source->price); + sub best_price { + return $price; + } - # for finer control - $price_source->needed_params - $price_source->supported_params + sub price_from_source { + return $price; + } =head1 DESCRIPTION -PriceSource is an interface that allows generic algorithms to be used, to -calculate a price for a position in a record. +See L for information about the mechanism. + +This is the base class for a price source algorithm. To play well, you'll have +to implement a number of interface methods and be aware of a number of corner +conditions. + +=head1 AVAILABLE METHODS + +=over 4 + +=item C + +=item C + +C can be any one of L, L, +L, L. C is of the +corresponding position type. + +You can assume that both are filled with all information available at the time. +C and C/C as well as C can be relied upon. You must NOT +rely on both being linked together, in particular + + $self->record_item->record # don't do that -If any such price_source algorithm is known to the system, a user can chose -which of them should be used to claculate the price displayed in the record. +is not guaranteed to work. -The algorithm is saved togetherwith the target price, so that changes in the -record can recalculate the price accordingly, and otherwise manual changes to -the price can reset the price_source used to custom (aka no price_source). +Also these are copies and not the original documents. Do not try to change +anything and do not save those. + +=item C + +Shortcut to C<< record_item->part >> + +=back =head1 INTERFACE METHODS @@ -70,32 +106,89 @@ the price can reset the price_source used to custom (aka no price_source). =item C -Should return a unique internal name. Should be entered in -L so that a name_to_class lookup works. +Must return a unique internal name. Must be entered in +L. =item C -Should return a translated name. +Must return a translated name to be used in frontend. Will be used, to +distinguish the origin of different prices. + +=item C -=item C +Must return a list of all prices that you algorithm can recommend the user +for the current situation. Each price must have a unique spec that can be used +to recreate it later. Try to be brief, no one needs 20 different price +suggestions. -Should return a list of elements that a record_item NEEDS to be used with this calulation. +=item C -Both C nad C are purely informational at this point. +Must return what you think of as the best matching price in your +C. This does not have to be the lowest price, but it will be +compared later to other price sources, and the lowest will be set. -=item C +=item C -Should return a list of elements that a record_item MAY HAVE to be used with this calulation. +Must recreate the price from C and return. For reference, the complete +C entry from C is included. -Both C nad C are purely informational at this point. +Note that constraints from the rest of the C do not apply anymore. If +information needed for the retrieval can be deleted elsewhere, then you must +guard against that. -=item C +If the price for the same coditions changed, return the new price. It will be +presented as an option to the user if the record is still editable. -Calculate a price and return. Do not mutate the record_item. Should will return -undef if price is not applicable to the current record_item. +If the price is not valid anymore or not reconstructable, return a price with +C and C set to the same values as before but with +C or C set. =back +=head1 TRAPS AND CORNER CASES + +=over 4 + +=item * + +Be aware that all 8 types of record will be passed to your algorithm. If you +don't serve some of them, just return emptry lists on C and +C + +=item * + +Information in C might be missing. Especially on newly or automatically +created records there might be fields not set at all. + +=item * + +Records will not be calculated. If you need tax data or position totals, you +need to invoke that for yourself. + +=item * + +Accessor methods might not be present in some of the record types. + +=item * + +You do not need to do price factor and row discount calculation. These will be +done automatically afterwards. You do have to include customer/vendor discount +if your price interacts with those. + +=item * + +The price field in purchase records is still C. + +=item * + +C and C are tainted. If you store data directly in C, sanitize. + +=head1 SEE ALSO + +L, +L, +L + =head1 BUGS None yet. :)