X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FPriceSource%2FBase.pm;h=1e8f20d9312b6b07e9e04bedeb1fcac8bce36a68;hb=deb4d2dbb676d7d6f69dfe7815d6e0cb09bd4a44;hp=618512d9486c280fb561961d5fd9e9094a230b4f;hpb=eebe8e90991eacadb6fbd20a648c152017a620c7;p=kivitendo-erp.git diff --git a/SL/PriceSource/Base.pm b/SL/PriceSource/Base.pm index 618512d94..1e8f20d93 100644 --- a/SL/PriceSource/Base.pm +++ b/SL/PriceSource/Base.pm @@ -13,14 +13,24 @@ sub description { die 'description needs to be implemented' } sub available_prices { die 'available_prices needs to be implemented' } +sub available_discounts { die 'available_discounts needs to be implemented' } + sub best_price { die 'best_price needs to be implemented' } +sub best_discounts { die 'best_discounts needs to be implemented' } + sub price_from_source { die 'price_from_source needs to be implemented:' . "@_" } +sub discount_from_source { die 'discount_from_source needs to be implemented:' . "@_" } + sub part { $_[0]->record_item->part; } +sub customer_vendor { + $_[0]->record->is_sales ? $_[0]->record->customer : $_[0]->record->vendor; +} + 1; __END__ @@ -29,40 +39,80 @@ __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; + + use parent qw(SL::PriceSource::Base); + + # used as internal identifier + sub name { 'simple' } - 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; + # 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 -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. +=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 + +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 >> + +=item C + +Shortcut to C<< record->is_sales ? record->customer : record->vendor >> + +=back =head1 INTERFACE METHODS @@ -70,32 +120,105 @@ 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 the frontend. Will be used to +distinguish the origin of different prices. -=item C +=item C -Should return a list of elements that a record_item NEEDS to be used with this calulation. +Must return a list of all prices that your algorithm can recommend to 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. -Both C nad C are purely informational at this point. +=item C -=item C +Must return a list of all prices that your algorithm can recommend to the user +for the current situation. Each discount must have a unique spec that can be +used to recreate it later. Try to be brief, no one needs 20 different discount +suggestions. -Should return a list of elements that a record_item MAY HAVE 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 -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. +Must return what you think of as the best matching discount in your +C. This does not have to be the highest discount, but it +will be compared later to other price sources, and the highest will be set. + +=item C + +Must recreate the price or discount from C and return. For reference, the +complete C entry from C or +C is included. + +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. + +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. + +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 empty 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 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 discounts +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. =back +=head1 SEE ALSO + +L, +L, +L + =head1 BUGS None yet. :)