From 0fe023a4ee7e467bfb5f23a87800b8723c8ccacd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sven=20Sch=C3=B6ling?= Date: Thu, 11 Sep 2014 18:14:13 +0200 Subject: [PATCH] PriceRule: Korrektes Matching von Nulls --- SL/DB/Manager/PriceRule.pm | 3 +-- SL/DB/Manager/PriceRuleItem.pm | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/SL/DB/Manager/PriceRule.pm b/SL/DB/Manager/PriceRule.pm index a3eeaff99..e94fd1546 100644 --- a/SL/DB/Manager/PriceRule.pm +++ b/SL/DB/Manager/PriceRule.pm @@ -27,8 +27,7 @@ sub get_matching_filter { my $type = $params{record}->is_sales ? 'customer' : 'vendor'; # plan: 1. search all rule_items that do NOT match this record/record item combo - my ($sub_where, @value_subs) = SL::DB::Manager::PriceRuleItem->not_matching_sql_and_values(type => $type); - my @values = map { $_->($params{record}, $params{record_item}) } @value_subs; + my ($sub_where, @values) = SL::DB::Manager::PriceRuleItem->not_matching_sql_and_values(type => $type, %params); # now union all NOT matching, invert ids, load these my $matching_rule_ids = < { description => t8('Customer'), customer => 1, vendor => 0, data_type => 'int', data => sub { $_[0]->customer->id }, }, 'vendor' => { description => t8('Vendor'), customer => 0, vendor => 1, data_type => 'int', data => sub { $_[0]->vendor->id }, }, - 'business' => { description => t8('Type of Business'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[0]->customervendor->business_id }, }, + 'business' => { description => t8('Type of Business'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[0]->customervendor->business_id }, exclude_nulls => 1 }, 'reqdate' => { description => t8('Reqdate'), customer => 1, vendor => 1, data_type => 'date', data => sub { $_[0]->reqdate }, ops => 'date' }, - 'pricegroup' => { description => t8('Pricegroup'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[1]->pricegroup_id }, }, - 'partsgroup' => { description => t8('Group'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[1]->part->partsgroup_id }, }, + 'pricegroup' => { description => t8('Pricegroup'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[1]->pricegroup_id }, exclude_nulls => 1 }, + 'partsgroup' => { description => t8('Group'), customer => 1, vendor => 1, data_type => 'int', data => sub { $_[1]->part->partsgroup_id }, exclude_nulls => 1 }, 'qty' => { description => t8('Qty'), customer => 1, vendor => 1, data_type => 'num', data => sub { $_[1]->qty }, ops => 'num' }, ); @@ -37,6 +37,7 @@ sub not_matching_sql_and_values { my ($class, %params) = @_; die 'must be called with a customer/vendor type' unless $params{type}; + my @args = @params{'record', 'record_item'}; my (@tokens, @values); @@ -44,19 +45,25 @@ sub not_matching_sql_and_values { my $def = $types{$type}; next unless $def->{$params{type}}; - if ($def->{ops}) { - my $ops = $ops{$def->{ops}}; + my $value = $def->{data}->(@args); + if ($def->{exclude_nulls} && !defined $value) { + push @tokens, "type = '$type'"; + } else { my @sub_tokens; - for (keys %$ops) { - push @sub_tokens, "op = '$_' AND NOT value_$def->{data_type} $ops->{$_} ?"; - push @values, $def->{data}; + if ($def->{ops}) { + my $ops = $ops{$def->{ops}}; + + for (keys %$ops) { + push @sub_tokens, "op = '$_' AND NOT value_$def->{data_type} $ops->{$_} ?"; + push @values, $value; + } + } else { + push @sub_tokens, "NOT value_$def->{data_type} = ?"; + push @values, $value; } push @tokens, "type = '$type' AND " . join ' OR ', map "($_)", @sub_tokens; - } else { - push @tokens, "type = '$type' AND NOT value_$def->{data_type} = ?"; - push @values, $def->{data}; } } -- 2.20.1