|  | use Test::More;
 | 
  
    |  | 
 | 
  
    |  | use strict;
 | 
  
    |  | 
 | 
  
    |  | use lib 't';
 | 
  
    |  | use utf8;
 | 
  
    |  | 
 | 
  
    |  | use Carp;
 | 
  
    |  | use Data::Dumper;
 | 
  
    |  | use Support::TestSetup;
 | 
  
    |  | use Test::Exception;
 | 
  
    |  | 
 | 
  
    |  | use SL::Controller::CustomVariableConfig;
 | 
  
    |  | 
 | 
  
    |  | use SL::Dev::ALL qw(:ALL);
 | 
  
    |  | use SL::DB::PriceRule;
 | 
  
    |  | use SL::DB::Project;
 | 
  
    |  | use SL::DB::CustomVariableConfig;
 | 
  
    |  | 
 | 
  
    |  | Support::TestSetup::login();
 | 
  
    |  | 
 | 
  
    |  | sub reset_db {
 | 
  
    |  |   SL::DB::Manager::PriceRule->delete_all(all => 1);
 | 
  
    |  |   SL::DB::Manager::CustomVariable->delete_all(all => 1);
 | 
  
    |  |   SL::DB::Manager::CustomVariableConfig->delete_all(all => 1);
 | 
  
    |  |   SL::DB::Manager::Order->delete_all(all => 1);
 | 
  
    |  |   SL::DB::Manager::Shipto->delete_all(all => 1);
 | 
  
    |  | 
 | 
  
    |  |   $::request->{_cache} = {};
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | {
 | 
  
    |  |   reset_db();
 | 
  
    |  | 
 | 
  
    |  |   # cvar price rules.
 | 
  
    |  |   # a select cvar price rule for one specific value A
 | 
  
    |  |   # and an order where the part has exactly that cvar set to first A and then B
 | 
  
    |  | 
 | 
  
    |  |   my $cvar_config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |     module      => 'IC',
 | 
  
    |  |     name        => "test",
 | 
  
    |  |     description => "test",
 | 
  
    |  |     type        => "select",
 | 
  
    |  |     options     => "A##B##C##D",
 | 
  
    |  |     default_value => "D",
 | 
  
    |  |     flags       => "editable=0",
 | 
  
    |  |     searchable  => 0,
 | 
  
    |  |     includeable => 0,
 | 
  
    |  |     included_by_default => 0,
 | 
  
    |  |   )->save->load;
 | 
  
    |  | 
 | 
  
    |  |   my $name = "price for test A";
 | 
  
    |  | 
 | 
  
    |  |   my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |     name  => $name,
 | 
  
    |  |     price => 1,
 | 
  
    |  |     type  => "customer",
 | 
  
    |  |     items => [
 | 
  
    |  |       SL::DB::PriceRuleItem->new(
 | 
  
    |  |         custom_variable_configs => $cvar_config,
 | 
  
    |  |         value_text              => "A",
 | 
  
    |  |         type                    => "cvar",
 | 
  
    |  |       ),
 | 
  
    |  |     ],
 | 
  
    |  |   )->save;
 | 
  
    |  | 
 | 
  
    |  |   my $order = create_sales_order()->save->load;
 | 
  
    |  | 
 | 
  
    |  |   $order->items_sorted->[0]->part->cvar_by_name('test')->value("A");
 | 
  
    |  |   $order->items_sorted->[0]->part->cvar_by_name('test')->save;
 | 
  
    |  | 
 | 
  
    |  |   ok(1 == grep({ $_->{name} eq $name } @{ SL::DB::Manager::PriceRule->get_all_matching(record => $order, record_item => $order->items_sorted->[0]) }), "editable=0 price rule matches");
 | 
  
    |  | 
 | 
  
    |  |   $order->items_sorted->[0]->part->cvar_by_name('test')->value("B");
 | 
  
    |  |   $order->items_sorted->[0]->part->cvar_by_name('test')->save;
 | 
  
    |  | 
 | 
  
    |  |   ok(0 == grep({ $_->{name} eq $name } @{ SL::DB::Manager::PriceRule->get_all_matching(record => $order, record_item => $order->items_sorted->[0]) }), "editable=0 price rule does not match");
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | {
 | 
  
    |  |   reset_db();
 | 
  
    |  | 
 | 
  
    |  |   # now try the same, but with an editable cvar config
 | 
  
    |  | 
 | 
  
    |  |   my $cvar_config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |     module      => 'IC',
 | 
  
    |  |     name        => "test",
 | 
  
    |  |     description => "test2",
 | 
  
    |  |     type        => "select",
 | 
  
    |  |     options     => "A##B##C##D",
 | 
  
    |  |     default_value => "D",
 | 
  
    |  |     flags       => "editable=1",
 | 
  
    |  |     searchable  => 0,
 | 
  
    |  |     includeable => 0,
 | 
  
    |  |     included_by_default => 0,
 | 
  
    |  |   )->save->load;
 | 
  
    |  | 
 | 
  
    |  |   my $name = "price for test A";
 | 
  
    |  | 
 | 
  
    |  |   my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |     name  => $name,
 | 
  
    |  |     price => 1,
 | 
  
    |  |     type  => "customer",
 | 
  
    |  |     items => [
 | 
  
    |  |       SL::DB::PriceRuleItem->new(
 | 
  
    |  |         custom_variable_configs => $cvar_config,
 | 
  
    |  |         value_text              => "A",
 | 
  
    |  |         type                    => "cvar",
 | 
  
    |  |       ),
 | 
  
    |  |     ],
 | 
  
    |  |   )->save;
 | 
  
    |  | 
 | 
  
    |  |   my $order = create_sales_order()->save->load;
 | 
  
    |  |   my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |   $item->cvar_by_name('test')->value("A");
 | 
  
    |  |   $item->cvar_by_name('test')->save;
 | 
  
    |  | 
 | 
  
    |  |   ok(1 == grep({ $_->{name} eq $name } @{ SL::DB::Manager::PriceRule->get_all_matching(record => $order, record_item => $item) }), "editable=1 price rule matches");
 | 
  
    |  | 
 | 
  
    |  |   $item->cvar_by_name('test')->value("B");
 | 
  
    |  |   $item->cvar_by_name('test')->save;
 | 
  
    |  | 
 | 
  
    |  |   ok(0 == grep({ $_->{name} eq $name } @{ SL::DB::Manager::PriceRule->get_all_matching(record => $order, record_item => $item) }), "editable=1 price rule does not match");
 | 
  
    |  | 
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | # structural test: check whether the registered CVar types in SL::DB::Manager::PriceRuleItem have all the possible types of SL::Controller::CustomVariableConfigs
 | 
  
    |  | for (@SL::Controller::CustomVariableConfig::types) {
 | 
  
    |  |   ok(exists $SL::DB::Manager::PriceRuleItem::price_rule_type_by_cvar_type{$_}, "PriceRuleItem has cvar config type $_ registered");
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | # k, now for a more broad test:
 | 
  
    |  | #
 | 
  
    |  | # we can have these modules in cvars:
 | 
  
    |  | #  - CT
 | 
  
    |  | #  - Contact
 | 
  
    |  | #  - IC
 | 
  
    |  | #  - Project
 | 
  
    |  | #  - ShipTo
 | 
  
    |  | #
 | 
  
    |  | # and the cvars themselves can have these types:
 | 
  
    |  | #  - select
 | 
  
    |  | #  - customer
 | 
  
    |  | #  - vendor
 | 
  
    |  | #  - part
 | 
  
    |  | #  - integer
 | 
  
    |  | #  - number
 | 
  
    |  | #  - date
 | 
  
    |  | #  - timestamp
 | 
  
    |  | #
 | 
  
    |  | #  ...with the numeric and date ones also having comparison ops
 | 
  
    |  | #
 | 
  
    |  | #
 | 
  
    |  | # to be matched against all different record/record items
 | 
  
    |  | #
 | 
  
    |  | #
 | 
  
    |  | # testing all of that is too much, so this will do some combinations:
 | 
  
    |  | #   1. a cvar config
 | 
  
    |  | #   2. a price_rule that uses both
 | 
  
    |  | #   3. record + record item that either uses that or not
 | 
  
    |  | #   4. expected behaviour
 | 
  
    |  | {
 | 
  
    |  |   sub test {
 | 
  
    |  |     my ($price_rule, $record, $record_item, $comment, $expected_match) = @_;
 | 
  
    |  | 
 | 
  
    |  |     # needed to clear cvar caches in price rule implementation
 | 
  
    |  |     $::request->{_cache} = {};
 | 
  
    |  | 
 | 
  
    |  |     my $matching_rules = SL::DB::Manager::PriceRule->get_all_matching(record => $record, record_item => $record_item);
 | 
  
    |  |     my @does_match = grep { $_->{name} eq $price_rule->name } @$matching_rules;
 | 
  
    |  | 
 | 
  
    |  |     if ($expected_match) {
 | 
  
    |  |       ok(@does_match && $price_rule->name eq $does_match[0]->name, "$comment - expected match, got @does_match");
 | 
  
    |  |     } else {
 | 
  
    |  |       ok(!@does_match, "$comment - expected no match, got @does_match");
 | 
  
    |  |     }
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "before critical customer date";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'CT',
 | 
  
    |  |       type => 'date',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_date              => DateTime->new(year => 2022, month => 12, day => 9),
 | 
  
    |  |           op                      => "lt",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, $name, 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->customer->cvar_by_name($name)->value(DateTime->new(year => 2022, month => 12, day => 12));
 | 
  
    |  |     $order->customer->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- too late", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->customer->cvar_by_name($name)->value(DateTime->new(year => 2022, month => 12, day => 5));
 | 
  
    |  |     $order->customer->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- early", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "contact number equals 1234";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'Contacts',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_num               => 1234,
 | 
  
    |  |           op                      => "eq",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- no contact", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->contact(SL::DB::Contact->new)->save;
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- null", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->contact->cvar_by_name($name)->value(45);
 | 
  
    |  |     $order->contact->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->contact->cvar_by_name($name)->value(1234);
 | 
  
    |  |     $order->contact->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "project part matches";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'Projects',
 | 
  
    |  |       type => 'part',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $part = new_part()->save;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_int               => $part->id,
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $project1 = SL::DB::Project->new(
 | 
  
    |  |       project_type   => SL::DB::Manager::ProjectType->find_by(description => 'Standard'),
 | 
  
    |  |       project_status => SL::DB::Manager::ProjectStatus->find_by(name => 'running'),
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- no project", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->globalproject($project1)->save;
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- global project, but no value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->globalproject->cvar_by_name($name)->value($item->part);
 | 
  
    |  |     $order->globalproject->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- global project, not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->globalproject->cvar_by_name($name)->value($part);
 | 
  
    |  |     $order->globalproject->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- global project, matching", 1);
 | 
  
    |  | 
 | 
  
    |  |     my $project2 = SL::DB::Project->new(
 | 
  
    |  |       project_type   => SL::DB::Manager::ProjectType->find_by(description => 'Standard'),
 | 
  
    |  |       project_status => SL::DB::Manager::ProjectStatus->find_by(name => 'running'),
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     $item->project($project2)->save;
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- item project, but no value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $item->project->cvar_by_name($name)->value($item->part);
 | 
  
    |  |     $item->project->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- item project, not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $item->project->cvar_by_name($name)->value($part);
 | 
  
    |  |     $item->project->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- item project, matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "part customer matches";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'IC',
 | 
  
    |  |       type => 'customer',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $customer = new_customer()->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "vendor",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_int               => $customer->id,
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_purchase_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- no value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $item->part->cvar_by_name($name)->value(new_customer());
 | 
  
    |  |     $item->part->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $item->part->cvar_by_name($name)->value($customer);
 | 
  
    |  |     $item->part->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "part number with default value 15 matches 15";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'IC',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       default_value => 15,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_num               => 15,
 | 
  
    |  |           op                      => "eq",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- default value", 1);
 | 
  
    |  | 
 | 
  
    |  |     $item->part->cvar_by_name($name)->value(20);
 | 
  
    |  |     $item->part->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $item->part->cvar_by_name($name)->value(15);
 | 
  
    |  |     $item->part->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "shipto cvar and price rule matching that";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'ShipTo',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_num               => 15,
 | 
  
    |  |           op                      => "eq",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  |     my $shipto = SL::DB::Shipto->new;
 | 
  
    |  |     $order->shipto($shipto);
 | 
  
    |  |     $order->save->load;
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- default value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->value(20);
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->value(15);
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "custom shipto cvar and price rule matching that";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'ShipTo',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_num               => 15,
 | 
  
    |  |           op                      => "eq",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  |     my $shipto = SL::DB::Shipto->new(trans_id => $order->id, module => 'OE')->save;
 | 
  
    |  | 
 | 
  
    |  |     ok(ref $order->custom_shipto eq 'SL::DB::Shipto', 'custom shipto is readable from order');
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- default value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->value(20);
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->value(15);
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "custom shipto cvar and price rule matching that";
 | 
  
    |  | 
 | 
  
    |  |     my $config = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'ShipTo',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $price_rule = SL::DB::PriceRule->new(
 | 
  
    |  |       name  => $name,
 | 
  
    |  |       price => 1,
 | 
  
    |  |       type  => "customer",
 | 
  
    |  |       items => [
 | 
  
    |  |         SL::DB::PriceRuleItem->new(
 | 
  
    |  |           custom_variable_configs => $config,
 | 
  
    |  |           value_num               => 15,
 | 
  
    |  |           op                      => "eq",
 | 
  
    |  |           type                    => "cvar",
 | 
  
    |  |         ),
 | 
  
    |  |       ],
 | 
  
    |  |     )->save;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  |     my $shipto1 = SL::DB::Shipto->new;
 | 
  
    |  |     $order->shipto($shipto1);
 | 
  
    |  |     my $shipto2 = SL::DB::Shipto->new(trans_id => $order->id, module => 'OE')->save;
 | 
  
    |  |     $order->save->load;
 | 
  
    |  | 
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- default value", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->value(20);
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching custom", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->value(15);
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- not matching custom, matching shipto", 0);
 | 
  
    |  | 
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->value(15);
 | 
  
    |  |     $order->custom_shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching both", 1);
 | 
  
    |  | 
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->value(20);
 | 
  
    |  |     $order->shipto->cvar_by_name($name)->save;
 | 
  
    |  |     test($price_rule, $order, $item, "$name -- matching custom, not matching shipto", 1);
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   {
 | 
  
    |  |     reset_db();
 | 
  
    |  | 
 | 
  
    |  |     my $name = "no price rule, but cvars exist with module requirementsspecs or type text";
 | 
  
    |  | 
 | 
  
    |  |     my $config1 = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'RequirementSpecs',
 | 
  
    |  |       type => 'number',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $config2 = SL::DB::CustomVariableConfig->new(
 | 
  
    |  |       module => 'Customer',
 | 
  
    |  |       type => 'text',
 | 
  
    |  |       name => $name,
 | 
  
    |  |       description => $name,
 | 
  
    |  |       searchable  => 0,
 | 
  
    |  |       includeable => 0,
 | 
  
    |  |       included_by_default => 0,
 | 
  
    |  |       flags => '',
 | 
  
    |  |     )->save->load;
 | 
  
    |  | 
 | 
  
    |  |     my $order = create_sales_order()->save->load;
 | 
  
    |  |     my $item = $order->items_sorted->[0];
 | 
  
    |  |     $order->save->load;
 | 
  
    |  | 
 | 
  
    |  |     test(undef, $order, $item, "$name -- nothing to match", 0);
 | 
  
    |  |   }
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | reset_db();
 | 
  
    |  | 
 | 
  
    |  | done_testing();
 |