PriceRule: Preisregeln können jetzt auch Rabatte
[kivitendo-erp.git] / SL / PriceSource / PriceRules.pm
index 697369d..c9cecf9 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use parent qw(SL::PriceSource::Base);
 
 use SL::PriceSource::Price;
+use SL::PriceSource::Discount;
 use SL::Locale::String;
 use SL::DB::PriceRule;
 use List::UtilsBy qw(min_by max_by);
@@ -15,45 +16,72 @@ sub description { t8('Price Rule') }
 sub available_rules {
   my ($self, %params) = @_;
 
-  SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
+  $self->{available} ||= SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
+}
+
+sub available_price_rules {
+  my $rules = $_[0]->available_rules;
+  grep { $_->price_type != SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
+}
+
+sub available_discount_rules {
+  my $rules = $_[0]->available_rules;
+  grep { $_->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
 }
 
 sub available_prices {
   my ($self, %params) = @_;
 
-  my $rules = $self->available_rules;
-
-  map { $self->make_price_from_rule($_) } @$rules;
+  map { $self->make_price_from_rule($_) } $self->available_price_rules;
 }
 
-sub available_discounts { }
+sub available_discounts {
+  my ($self, %params) = @_;
+
+  map { $self->make_discount_from_rule($_) } $self->available_discount_rules;
+}
 
 sub price_from_source {
   my ($self, $source, $spec) = @_;
 
   my $rule = SL::DB::Manager::PriceRule->find_by(id => $spec);
-  $self->make_price_from_rule($rule);
+  if ($rule->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
+    return $self->make_discount_from_rule($rule);
+  } else {
+    return $self->make_price_from_rule($rule);
+  }
 }
 
 sub best_price {
   my ($self) = @_;
 
-  my $rules     = $self->available_rules;
+  my @rules     = $self->available_price_rules;
 
-  return unless @$rules;
+  return unless @rules;
 
-  my @max_prio  = max_by { $_->priority } @$rules;
+  my @max_prio  = max_by { $_->priority } @rules;
   my $min_price = min_by { $self->price_for_rule($_) } @max_prio;
 
   $self->make_price_from_rule($min_price);
 }
 
-sub best_discount { }
+sub best_discount {
+  my ($self) = @_;
+
+  my @rules     = $self->available_discount_rules;
+
+  return unless @rules;
+
+  my @max_prio     = max_by { $_->priority } @rules;
+  my $max_discount = max_by { $_->discount } @max_prio;
+
+  $self->make_discount_from_rule($max_discount);
+}
 
 sub price_for_rule {
   my ($self, $rule) = @_;
-  $rule->price_or_discount
-    ? (1 - $rule->discount / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
+  $rule->price_type != SL::DB::Manager::PriceRule::PRICE_NEW()
+    ? (1 - $rule->reduction / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
     : $rule->price;
 }
 
@@ -68,4 +96,15 @@ sub make_price_from_rule {
   )
 }
 
+sub make_discount_from_rule {
+  my ($self, $rule) = @_;
+
+  SL::PriceSource::Discount->new(
+    discount     => $rule->discount / 100,
+    spec         => $rule->id,
+    description  => $rule->name,
+    price_source => $self,
+  )
+}
+
 1;