1 package Koha::CirculationRules;
3 # Copyright ByWater Solutions 2017
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 use Koha::CirculationRule;
25 use base qw(Koha::Objects);
29 Koha::CirculationRules - Koha CirculationRule Object set class
39 This structure describes the possible rules that may be set, and what scopes they can be set at.
41 Any attempt to set a rule with a nonsensical scope (for instance, setting the C<patron_maxissueqty> for a branchcode and itemtype), is an error.
47 scope => [ 'branchcode' ],
50 patron_maxissueqty => {
51 scope => [ 'branchcode', 'categorycode' ],
53 patron_maxonsiteissueqty => {
54 scope => [ 'branchcode', 'categorycode' ],
57 scope => [ 'branchcode', 'categorycode' ],
61 scope => [ 'branchcode', 'itemtype' ],
63 hold_fulfillment_policy => {
64 scope => [ 'branchcode', 'itemtype' ],
67 scope => [ 'branchcode', 'itemtype' ],
71 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
74 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
76 cap_fine_to_replacement_price => {
77 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
80 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
82 chargeperiod_charge_at => {
83 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
86 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
89 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
92 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
95 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
97 hardduedatecompare => {
98 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
100 holds_per_record => {
101 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
104 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
107 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
110 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
112 maxonsiteissueqty => {
113 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
115 maxsuspensiondays => {
116 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
118 no_auto_renewal_after => {
119 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
121 no_auto_renewal_after_hard_limit => {
122 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
125 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
128 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
131 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
134 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
137 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
140 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
143 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
146 scope => [ 'branchcode', 'categorycode', 'itemtype' ],
148 # Not included (deprecated?):
159 =head3 get_effective_rule
163 sub get_effective_rule {
164 my ( $self, $params ) = @_;
166 $params->{categorycode} //= undef;
167 $params->{branchcode} //= undef;
168 $params->{itemtype} //= undef;
170 my $rule_name = $params->{rule_name};
171 my $categorycode = $params->{categorycode};
172 my $itemtype = $params->{itemtype};
173 my $branchcode = $params->{branchcode};
175 Koha::Exceptions::MissingParameter->throw(
176 "Required parameter 'rule_name' missing")
179 for my $v ( $branchcode, $categorycode, $itemtype ) {
180 $v = undef if $v and $v eq '*';
183 my $order_by = $params->{order_by}
184 // { -desc => [ 'branchcode', 'categorycode', 'itemtype' ] };
187 $search_params->{rule_name} = $rule_name;
189 $search_params->{categorycode} = defined $categorycode ? [ $categorycode, undef ] : undef;
190 $search_params->{itemtype} = defined $itemtype ? [ $itemtype, undef ] : undef;
191 $search_params->{branchcode} = defined $branchcode ? [ $branchcode, undef ] : undef;
193 my $rule = $self->search(
196 order_by => $order_by,
204 =head3 get_effective_rule
208 sub get_effective_rules {
209 my ( $self, $params ) = @_;
211 my $rules = $params->{rules};
212 my $categorycode = $params->{categorycode};
213 my $itemtype = $params->{itemtype};
214 my $branchcode = $params->{branchcode};
217 foreach my $rule (@$rules) {
218 my $effective_rule = $self->get_effective_rule(
221 categorycode => $categorycode,
222 itemtype => $itemtype,
223 branchcode => $branchcode,
227 $r->{$rule} = $effective_rule->rule_value if $effective_rule;
238 my ( $self, $params ) = @_;
240 for my $mandatory_parameter (qw( branchcode categorycode itemtype rule_name rule_value ) ){
241 Koha::Exceptions::MissingParameter->throw(
242 "Required parameter 'branchcode' missing")
243 unless exists $params->{$mandatory_parameter};
245 my $kind_info = $RULE_KINDS->{ $params->{rule_name} };
246 croak "set_rule given unknown rule '$params->{rule_name}'!"
247 unless defined $kind_info;
249 # Enforce scope; a rule should be set for its defined scope, no more, no less.
250 foreach my $scope_level ( qw( branchcode categorycode itemtype ) ) {
251 if ( grep /$scope_level/, @{ $kind_info->{scope} } ) {
252 croak "set_rule needs '$scope_level' to set '$params->{rule_name}'!"
253 unless exists $params->{$scope_level};
255 croak "set_rule cannot set '$params->{rule_name}' for a '$scope_level'!"
256 if exists $params->{$scope_level};
260 my $branchcode = $params->{branchcode};
261 my $categorycode = $params->{categorycode};
262 my $itemtype = $params->{itemtype};
263 my $rule_name = $params->{rule_name};
264 my $rule_value = $params->{rule_value};
266 for my $v ( $branchcode, $categorycode, $itemtype ) {
267 $v = undef if $v and $v eq '*';
269 my $rule = $self->search(
271 rule_name => $rule_name,
272 branchcode => $branchcode,
273 categorycode => $categorycode,
274 itemtype => $itemtype,
279 if ( defined $rule_value ) {
280 $rule->rule_value($rule_value);
288 if ( defined $rule_value ) {
289 $rule = Koha::CirculationRule->new(
291 branchcode => $branchcode,
292 categorycode => $categorycode,
293 itemtype => $itemtype,
294 rule_name => $rule_name,
295 rule_value => $rule_value,
310 my ( $self, $params ) = @_;
313 $set_params{branchcode} = $params->{branchcode} if exists $params->{branchcode};
314 $set_params{categorycode} = $params->{categorycode} if exists $params->{categorycode};
315 $set_params{itemtype} = $params->{itemtype} if exists $params->{itemtype};
316 my $rules = $params->{rules};
318 my $rule_objects = [];
319 while ( my ( $rule_name, $rule_value ) = each %$rules ) {
320 my $rule_object = Koha::CirculationRules->set_rule(
323 rule_name => $rule_name,
324 rule_value => $rule_value,
327 push( @$rule_objects, $rule_object );
330 return $rule_objects;
335 Delete a set of circulation rules, needed for cleaning up when deleting issuingrules
342 while ( my $rule = $self->next ){
347 =head3 get_onshelfholds_policy
349 my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy({ item => $item, patron => $patron });
353 sub get_onshelfholds_policy {
354 my ( $class, $params ) = @_;
355 my $item = $params->{item};
356 my $itemtype = $item->effective_itemtype;
357 my $patron = $params->{patron};
358 my $rule = Koha::CirculationRules->get_effective_rule(
360 categorycode => ( $patron ? $patron->categorycode : undef ),
361 itemtype => $itemtype,
362 branchcode => $item->holdingbranch,
363 rule_name => 'onshelfholds',
366 return $rule ? $rule->rule_value : undef;
374 return 'CirculationRule';
382 return 'Koha::CirculationRule';