From d977b4e5c431c8fc89169a4792b2e89965b948a4 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 6 Dec 2018 16:27:50 -0300 Subject: [PATCH] Bug 18936: Move guess_article_requestable_itemtypes method --- Koha/CirculationRules.pm | 67 ++++++++++++++++++++++ Koha/ItemType.pm | 4 +- admin/smart-rules.pl | 2 +- opac/opac-search.pl | 3 +- t/db_dependent/ArticleRequests.t | 4 +- .../guess_article_requestable_itemtypes.t | 24 ++++---- 6 files changed, 86 insertions(+), 18 deletions(-) diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index 906a3c54ad..a6ed947ebe 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -24,6 +24,8 @@ use Koha::CirculationRule; use base qw(Koha::Objects); +use constant GUESSED_ITEMTYPES_KEY => 'Koha_IssuingRules_last_guess'; + =head1 NAME Koha::CirculationRules - Koha CirculationRule Object set class @@ -396,6 +398,71 @@ sub get_onshelfholds_policy { return $rule ? $rule->rule_value : undef; } +=head3 article_requestable_rules + + Return rules that allow article requests, optionally filtered by + patron categorycode. + + Use with care; see guess_article_requestable_itemtypes. + +=cut + +sub article_requestable_rules { + my ( $class, $params ) = @_; + my $category = $params->{categorycode}; + + return if !C4::Context->preference('ArticleRequests'); + return $class->search({ + $category ? ( categorycode => [ $category, '*' ] ) : (), + rule_name => 'article_requests', + rule_value => { '!=' => 'no' }, + }); +} + +=head3 guess_article_requestable_itemtypes + + Return item types in a hashref that are likely possible to be + 'article requested'. Constructed by an intelligent guess in the + issuing rules (see article_requestable_rules). + + Note: pref ArticleRequestsLinkControl overrides the algorithm. + + Optional parameters: categorycode. + + Note: the routine is used in opac-search to obtain a reasonable + estimate within performance borders (not looking at all items but + just using default itemtype). Also we are not looking at the + branchcode here, since home or holding branch of the item is + leading and branch may be unknown too (anonymous opac session). + +=cut + +sub guess_article_requestable_itemtypes { + my ( $class, $params ) = @_; + my $category = $params->{categorycode}; + return {} if !C4::Context->preference('ArticleRequests'); + return { '*' => 1 } if C4::Context->preference('ArticleRequestsLinkControl') eq 'always'; + + my $cache = Koha::Caches->get_instance; + my $last_article_requestable_guesses = $cache->get_from_cache(GUESSED_ITEMTYPES_KEY); + my $key = $category || '*'; + return $last_article_requestable_guesses->{$key} + if $last_article_requestable_guesses && exists $last_article_requestable_guesses->{$key}; + + my $res = {}; + my $rules = $class->article_requestable_rules({ + $category ? ( categorycode => $category ) : (), + }); + return $res if !$rules; + foreach my $rule ( $rules->as_list ) { + $res->{ $rule->itemtype } = 1; + } + $last_article_requestable_guesses->{$key} = $res; + $cache->set_in_cache(GUESSED_ITEMTYPES_KEY, $last_article_requestable_guesses); + return $res; +} + + =head3 type =cut diff --git a/Koha/ItemType.pm b/Koha/ItemType.pm index e33f0e66e4..ba6428a0dd 100644 --- a/Koha/ItemType.pm +++ b/Koha/ItemType.pm @@ -22,7 +22,7 @@ use Carp; use C4::Koha; use C4::Languages; use Koha::Database; -use Koha::IssuingRules; +use Koha::CirculationRules; use Koha::Localizations; use base qw(Koha::Object Koha::Object::Limit::Library); @@ -119,7 +119,7 @@ sub may_article_request { my $itemtype = $self->itemtype; my $category = $params->{categorycode}; - my $guess = Koha::IssuingRules->guess_article_requestable_itemtypes({ + my $guess = Koha::CirculationRules->guess_article_requestable_itemtypes({ $category ? ( categorycode => $category ) : (), }); return ( $guess->{ $itemtype // q{} } || $guess->{ '*' } ) ? 1 : q{}; diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 8a228075b1..631baf45f5 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -72,7 +72,7 @@ my $op = $input->param('op') || q{}; my $language = C4::Languages::getlanguage(); my $cache = Koha::Caches->get_instance; -$cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY ); +$cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY ); if ($op eq 'delete') { my $itemtype = $input->param('itemtype'); diff --git a/opac/opac-search.pl b/opac/opac-search.pl index ea78ca0b23..e762b65d45 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -52,6 +52,7 @@ use C4::Tags qw(get_tags); use C4::SocialData; use C4::External::OverDrive; +use Koha::CirculationRules; use Koha::Libraries; use Koha::ItemTypes; use Koha::Ratings; @@ -676,7 +677,7 @@ for (my $i=0;$i<@servers;$i++) { my $art_req_itypes; if( C4::Context->preference('ArticleRequests') ) { - $art_req_itypes = Koha::IssuingRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () }); + $art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () }); } foreach my $res (@newresults) { diff --git a/t/db_dependent/ArticleRequests.t b/t/db_dependent/ArticleRequests.t index f9aee4138a..44a99b7e62 100755 --- a/t/db_dependent/ArticleRequests.t +++ b/t/db_dependent/ArticleRequests.t @@ -252,7 +252,7 @@ subtest 'may_article_request' => sub { # mocking t::lib::Mocks::mock_preference('ArticleRequests', 1); t::lib::Mocks::mock_preference('ArticleRequestsLinkControl', 'calc'); - $cache->set_in_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY, { + $cache->set_in_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY, { '*' => { 'CR' => 1 }, 'S' => { '*' => 1 }, 'PT' => { 'BK' => 1 }, @@ -266,7 +266,7 @@ subtest 'may_article_request' => sub { is( $itemtype->may_article_request({ categorycode => 'PT' }), '1', 'Result should be true when LinkControl is set to always' ); # Cleanup - $cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY ); + $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY ); }; $schema->storage->txn_rollback(); diff --git a/t/db_dependent/Koha/IssuingRules/guess_article_requestable_itemtypes.t b/t/db_dependent/Koha/IssuingRules/guess_article_requestable_itemtypes.t index ae716db5dc..dc5203dfd5 100644 --- a/t/db_dependent/Koha/IssuingRules/guess_article_requestable_itemtypes.t +++ b/t/db_dependent/Koha/IssuingRules/guess_article_requestable_itemtypes.t @@ -6,7 +6,7 @@ use Test::More tests => 1; use t::lib::Mocks; use t::lib::TestBuilder; use Koha::Database; -use Koha::IssuingRules; +use Koha::CirculationRules; use Koha::Caches; my $schema = Koha::Database->new->schema; @@ -19,14 +19,14 @@ subtest 'guess_article_requestable_itemtypes' => sub { t::lib::Mocks::mock_preference('ArticleRequests', 1); t::lib::Mocks::mock_preference('ArticleRequestsLinkControl', 'calc'); - $cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY ); - Koha::IssuingRules->delete; + $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY ); + Koha::CirculationRules->delete; my $itype1 = $builder->build_object({ class => 'Koha::ItemTypes' }); my $itype2 = $builder->build_object({ class => 'Koha::ItemTypes' }); my $catg1 = $builder->build_object({ class => 'Koha::Patron::Categories' }); my $catg2 = $builder->build_object({ class => 'Koha::Patron::Categories' }); my $rule1 = $builder->build_object({ - class => 'Koha::IssuingRules', + class => 'Koha::CirculationRules', value => { branchcode => 'MPL', # no worries: no FK categorycode => '*', @@ -35,7 +35,7 @@ subtest 'guess_article_requestable_itemtypes' => sub { }, }); my $rule2 = $builder->build_object({ - class => 'Koha::IssuingRules', + class => 'Koha::CirculationRules', value => { branchcode => '*', categorycode => $catg1->categorycode, @@ -44,33 +44,33 @@ subtest 'guess_article_requestable_itemtypes' => sub { }, }); - my $res = Koha::IssuingRules->guess_article_requestable_itemtypes; + my $res = Koha::CirculationRules->guess_article_requestable_itemtypes; is( $res->{'*'}, undef, 'Item type * seems not permitted' ); is( $res->{$itype1->itemtype}, 1, 'Item type 1 seems permitted' ); is( $res->{$itype2->itemtype}, 1, 'Item type 2 seems permitted' ); - $res = Koha::IssuingRules->guess_article_requestable_itemtypes({ categorycode => $catg2->categorycode }); + $res = Koha::CirculationRules->guess_article_requestable_itemtypes({ categorycode => $catg2->categorycode }); is( $res->{'*'}, undef, 'Item type * seems not permitted' ); is( $res->{$itype1->itemtype}, 1, 'Item type 1 seems permitted' ); is( $res->{$itype2->itemtype}, undef, 'Item type 2 seems not permitted' ); # Change the rules $rule2->itemtype('*')->store; - $cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY ); - $res = Koha::IssuingRules->guess_article_requestable_itemtypes; + $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY ); + $res = Koha::CirculationRules->guess_article_requestable_itemtypes; is( $res->{'*'}, 1, 'Item type * seems permitted' ); is( $res->{$itype1->itemtype}, 1, 'Item type 1 seems permitted' ); is( $res->{$itype2->itemtype}, undef, 'Item type 2 seems not permitted' ); - $res = Koha::IssuingRules->guess_article_requestable_itemtypes({ categorycode => $catg2->categorycode }); + $res = Koha::CirculationRules->guess_article_requestable_itemtypes({ categorycode => $catg2->categorycode }); is( $res->{'*'}, undef, 'Item type * seems not permitted' ); is( $res->{$itype1->itemtype}, 1, 'Item type 1 seems permitted' ); is( $res->{$itype2->itemtype}, undef, 'Item type 2 seems not permitted' ); # Finally test the overriding pref t::lib::Mocks::mock_preference('ArticleRequestsLinkControl', 'always'); - $res = Koha::IssuingRules->guess_article_requestable_itemtypes({}); + $res = Koha::CirculationRules->guess_article_requestable_itemtypes({}); is( $res->{'*'}, 1, 'Override algorithm with pref setting' ); - $cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY ); + $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY ); }; $schema->storage->txn_rollback; -- 2.11.0