From 259a5727def9f5b9655498e68c8e498c7e0db9f5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sven=20Sch=C3=B6ling?= Date: Thu, 18 Jan 2018 15:03:37 +0100 Subject: [PATCH] PriceSource: Objekte cachen. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Im Moment werden die einzelnen Worker im normalen Workflow mehrfach angelegt, einmal für die verfügbaren, und dann noch einmal für den besten und zum wiederherstellen der existierenden. Für größere Belege wird das merklich, und bei komplexen Implementationen, die auf die Datenbank zugreifen müssen, sogar mehrere Sekunden. Diese Patch ist der erste in einer Reihe, die es erlauben optional Preisquellen 1. nicht unnötig zu erstellen 2. in sich cachen zu lassen 3. vorberechnen zu lassen und damit horizontal zu cachen 3. die Berechnungen in einen Ajax Call zu verzögern --- SL/PriceSource.pm | 60 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/SL/PriceSource.pm b/SL/PriceSource.pm index 014abdda9..6fd3cbcee 100644 --- a/SL/PriceSource.pm +++ b/SL/PriceSource.pm @@ -4,7 +4,13 @@ use strict; use parent 'SL::DB::Object'; use Rose::Object::MakeMethods::Generic ( scalar => [ qw(record_item record) ], - 'array --get_set_init' => [ qw(all_price_sources) ], + 'scalar --get_set_init' => [ qw( + best_price best_discount + ) ], + 'array --get_set_init' => [ qw( + all_price_sources + available_prices available_discounts + ) ], ); use List::UtilsBy qw(min_by max_by); @@ -16,46 +22,62 @@ sub init_all_price_sources { my ($self) = @_; [ map { - $_->new(record_item => $self->record_item, record => $self->record) + $self->price_source_by_class($_); } SL::PriceSource::ALL->all_enabled_price_sources ] } +sub price_source_by_class { + my ($self, $class) = @_; + return unless $class; + + $self->{price_source_by_name}{$class} //= + $class->new(record_item => $self->record_item, record => $self->record); +} + sub price_from_source { my ($self, $source) = @_; - my ($source_name, $spec) = split m{/}, $source, 2; + return empty_price() if !$source; - my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); + ${ $self->{price_from_source} //= {} }{$source} //= do { + my ($source_name, $spec) = split m{/}, $source, 2; + my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); + my $source_object = $self->price_source_by_class($class); - return $class - ? $class->new(record_item => $self->record_item, record => $self->record)->price_from_source($source, $spec) - : empty_price(); + $source_object + ? $source_object->price_from_source($source, $spec) + : empty_price(); + } } sub discount_from_source { my ($self, $source) = @_; - my ($source_name, $spec) = split m{/}, $source, 2; + return empty_discount() if !$source; - my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); + ${ $self->{discount_from_source} //= {} }{$source} //= do { + my ($source_name, $spec) = split m{/}, $source, 2; + my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); + my $source_object = $self->price_source_by_class($class); - return $class - ? $class->new(record_item => $self->record_item, record => $self->record)->discount_from_source($source, $spec) - : empty_discount(); + $source_object + ? $source_object->discount_from_source($source, $spec) + : empty_discount(); + } } -sub available_prices { - map { $_->available_prices } $_[0]->all_price_sources; +sub init_available_prices { + [ map { $_->available_prices } $_[0]->all_price_sources ]; } -sub available_discounts { - return if $_[0]->record_item->part->not_discountable; - map { $_->available_discounts } $_[0]->all_price_sources; +sub init_available_discounts { + return [] if $_[0]->record_item->part->not_discountable; + [ map { $_->available_discounts } $_[0]->all_price_sources ]; } -sub best_price { +sub init_best_price { min_by { $_->price } max_by { $_->priority } grep { $_->price > 0 } grep { $_ } map { $_->best_price } $_[0]->all_price_sources; } -sub best_discount { +sub init_best_discount { max_by { $_->discount } max_by { $_->priority } grep { $_->discount } grep { $_ } map { $_->best_discount } $_[0]->all_price_sources; } -- 2.20.1