Bug 17530: Add Koha::IssuingRules->guess_article_requestable_itemtypes
[koha.git] / Koha / IssuingRules.pm
1 package Koha::IssuingRules;
2
3 # Copyright Vaara-kirjastot 2015
4 # Copyright Koha Development Team 2016
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 3 of the License, or (at your option) any later
11 # version.
12 #
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License along
18 # with Koha; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 use Modern::Perl;
22
23 use Koha::Database;
24
25 use Koha::IssuingRule;
26
27 use base qw(Koha::Objects);
28
29 =head1 NAME
30
31 Koha::IssuingRules - Koha IssuingRule Object set class
32
33 =head1 API
34
35 =head2 Class Methods
36
37 =cut
38
39 sub get_effective_issuing_rule {
40     my ( $self, $params ) = @_;
41
42     my $default      = '*';
43     my $categorycode = $params->{categorycode};
44     my $itemtype     = $params->{itemtype};
45     my $branchcode   = $params->{branchcode};
46
47     my $search_categorycode = $default;
48     my $search_itemtype     = $default;
49     my $search_branchcode   = $default;
50
51     if ($categorycode) {
52         $search_categorycode = { 'in' => [ $categorycode, $default ] };
53     }
54     if ($itemtype) {
55         $search_itemtype = { 'in' => [ $itemtype, $default ] };
56     }
57     if ($branchcode) {
58         $search_branchcode = { 'in' => [ $branchcode, $default ] };
59     }
60
61     my $rule = $self->search({
62         categorycode => $search_categorycode,
63         itemtype     => $search_itemtype,
64         branchcode   => $search_branchcode,
65     }, {
66         order_by => {
67             -desc => ['branchcode', 'categorycode', 'itemtype']
68         },
69         rows => 1,
70     })->single;
71     return $rule;
72 }
73
74 =head3 get_opacitemholds_policy
75
76 my $can_place_a_hold_at_item_level = Koha::IssuingRules->get_opacitemholds_policy( { patron => $patron, item => $item } );
77
78 Return 'Y' or 'F' if the patron can place a hold on this item according to the issuing rules
79 and the "Item level holds" (opacitemholds).
80 Can be 'N' - Don't allow, 'Y' - Allow, and 'F' - Force
81
82 =cut
83
84 sub get_opacitemholds_policy {
85     my ( $class, $params ) = @_;
86
87     my $item   = $params->{item};
88     my $patron = $params->{patron};
89
90     return unless $item or $patron;
91
92     my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
93         {
94             categorycode => $patron->categorycode,
95             itemtype     => $item->effective_itemtype,
96             branchcode   => $item->homebranch,
97         }
98     );
99
100     return $issuing_rule ? $issuing_rule->opacitemholds : undef;
101 }
102
103 =head3 get_onshelfholds_policy
104
105     my $on_shelf_holds = Koha::IssuingRules->get_onshelfholds_policy({ item => $item, patron => $patron });
106
107 =cut
108
109 sub get_onshelfholds_policy {
110     my ( $class, $params ) = @_;
111     my $item = $params->{item};
112     my $itemtype = $item->effective_itemtype;
113     my $patron = $params->{patron};
114     my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
115         {
116             ( $patron ? ( categorycode => $patron->categorycode ) : () ),
117             itemtype   => $itemtype,
118             branchcode => $item->holdingbranch
119         }
120     );
121     return $issuing_rule ? $issuing_rule->onshelfholds : undef;
122 }
123
124 =head3 article_requestable_rules
125
126     Return rules that allow article requests, optionally filtered by
127     patron categorycode.
128
129     Use with care; see guess_article_requestable_itemtypes.
130
131 =cut
132
133 sub article_requestable_rules {
134     my ( $class_or_self, $params ) = @_;
135     my $category = $params->{categorycode};
136
137     return if !C4::Context->preference('ArticleRequests');
138     return $class_or_self->search({
139         $category ? ( categorycode => [ $category, '*' ] ) : (),
140         article_requests => { '!=' => 'no' },
141     });
142 }
143
144 =head3 guess_article_requestable_itemtypes
145
146     Return item types in a hashref that are likely possible to be
147     'article requested'. Constructed by an intelligent guess in the
148     issuing rules (see article_requestable_rules).
149
150     Optional parameters: categorycode.
151
152     Note: the routine is used in opac-search to obtain a reasonable
153     estimate within performance borders (not looking at all items but
154     just using default itemtype). Also we are not looking at the
155     branchcode here, since home or holding branch of the item is
156     leading and branch may be unknown too (anonymous opac session).
157
158 =cut
159
160 our $last_article_requestable_guesses; # used during Plack life time
161
162 sub guess_article_requestable_itemtypes {
163     my ( $class_or_self, $params ) = @_;
164     my $category = $params->{categorycode};
165     return {} if !C4::Context->preference('ArticleRequests');
166
167     my $key = $category || '*';
168     return $last_article_requestable_guesses->{$key}
169         if $last_article_requestable_guesses && exists $last_article_requestable_guesses->{$key};
170
171     my $res = {};
172     my $rules = $class_or_self->article_requestable_rules({
173         $category ? ( categorycode => $category ) : (),
174     });
175     return $res if !$rules;
176     foreach my $rule ( $rules->as_list ) {
177         $res->{ $rule->itemtype } = 1;
178     }
179     $last_article_requestable_guesses->{$key} = $res;
180     return $res;
181 }
182
183 =head3 type
184
185 =cut
186
187 sub _type {
188     return 'Issuingrule';
189 }
190
191 sub object_class {
192     return 'Koha::IssuingRule';
193 }
194
195 1;