Bug 18936: Move guess_article_requestable_itemtypes method
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 6 Dec 2018 19:27:50 +0000 (16:27 -0300)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Tue, 4 Feb 2020 09:56:25 +0000 (09:56 +0000)
Signed-off-by: Minna Kivinen <minna.kivinen@hamk.fi>
Signed-off-by: Joonas Kylmälä <joonas.kylmala@helsinki.fi>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Koha/CirculationRules.pm
Koha/ItemType.pm
admin/smart-rules.pl
opac/opac-search.pl
t/db_dependent/ArticleRequests.t
t/db_dependent/Koha/IssuingRules/guess_article_requestable_itemtypes.t

index 906a3c5..a6ed947 100644 (file)
@@ -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
index e33f0e6..ba6428a 100644 (file)
@@ -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{};
index 8a22807..631baf4 100755 (executable)
@@ -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');
index 96264e4..f8a603f 100755 (executable)
@@ -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) {
index f9aee41..44a99b7 100755 (executable)
@@ -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();
index ae716db..dc5203d 100644 (file)
@@ -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;