Bug 8367: (follow-up) Fix pickup delay text on OPAC and other bits
[koha.git] / admin / smart-rules.pl
1 #!/usr/bin/perl
2 # Copyright 2000-2002 Katipo Communications
3 # copyright 2010 BibLibre
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21 use CGI qw ( -utf8 );
22 use C4::Context;
23 use C4::Output qw( output_html_with_http_headers );
24 use C4::Auth qw( get_template_and_user );
25 use Koha::Exception;
26 use Koha::Database;
27 use Koha::Logger;
28 use Koha::Libraries;
29 use Koha::CirculationRules;
30 use Koha::Patron::Categories;
31 use Koha::Caches;
32 use Koha::Patrons;
33
34 my $input = CGI->new;
35 my $dbh = C4::Context->dbh;
36
37 # my $flagsrequired;
38 # $flagsrequired->{circulation}=1;
39 my ($template, $loggedinuser, $cookie)
40     = get_template_and_user({template_name => "admin/smart-rules.tt",
41                             query => $input,
42                             type => "intranet",
43                             flagsrequired => {parameters => 'manage_circ_rules'},
44                             });
45
46 my $type=$input->param('type');
47
48 my $branch = $input->param('branch');
49 unless ( $branch ) {
50     if ( C4::Context->preference('DefaultToLoggedInLibraryCircRules') ) {
51         $branch = Koha::Libraries->search->count() == 1 ? undef : C4::Context::mybranch();
52     }
53     else {
54         $branch = C4::Context::only_my_library() ? ( C4::Context::mybranch() || '*' ) : '*';
55     }
56 }
57
58 my $logged_in_patron = Koha::Patrons->find( $loggedinuser );
59
60 my $can_edit_from_any_library = $logged_in_patron->has_permission( {parameters => 'manage_circ_rules_from_any_libraries' } );
61 $template->param( restricted_to_own_library => not $can_edit_from_any_library );
62 $branch = C4::Context::mybranch() unless $can_edit_from_any_library;
63
64 my $op = $input->param('op') || q{};
65 my $language = C4::Languages::getlanguage();
66
67 my $cache = Koha::Caches->get_instance;
68 $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY );
69
70 if ($op eq 'delete') {
71     my $itemtype     = $input->param('itemtype');
72     my $categorycode = $input->param('categorycode');
73
74     Koha::CirculationRules->set_rules(
75         {
76             categorycode => $categorycode eq '*' ? undef : $categorycode,
77             branchcode   => $branch eq '*' ? undef : $branch,
78             itemtype     => $itemtype eq '*' ? undef : $itemtype,
79             rules        => {
80                 maxissueqty                      => undef,
81                 maxonsiteissueqty                => undef,
82                 rentaldiscount                   => undef,
83                 fine                             => undef,
84                 finedays                         => undef,
85                 maxsuspensiondays                => undef,
86                 suspension_chargeperiod          => undef,
87                 firstremind                      => undef,
88                 chargeperiod                     => undef,
89                 chargeperiod_charge_at           => undef,
90                 issuelength                      => undef,
91                 daysmode                         => undef,
92                 lengthunit                       => undef,
93                 hardduedate                      => undef,
94                 hardduedatecompare               => undef,
95                 renewalsallowed                  => undef,
96                 unseen_renewals_allowed          => undef,
97                 renewalperiod                    => undef,
98                 norenewalbefore                  => undef,
99                 noautorenewalbefore              => undef,
100                 auto_renew                       => undef,
101                 no_auto_renewal_after            => undef,
102                 no_auto_renewal_after_hard_limit => undef,
103                 reservesallowed                  => undef,
104                 holds_per_record                 => undef,
105                 holds_per_day                    => undef,
106                 onshelfholds                     => undef,
107                 opacitemholds                    => undef,
108                 overduefinescap                  => undef,
109                 cap_fine_to_replacement_price    => undef,
110                 article_requests                 => undef,
111                 note                             => undef,
112                 recalls_allowed                  => undef,
113                 recalls_per_record               => undef,
114                 on_shelf_recalls                 => undef,
115                 recall_due_date_interval         => undef,
116                 recall_overdue_fine              => undef,
117                 recall_shelf_time                => undef,
118                 decreaseloanholds                => undef,
119             }
120         }
121     );
122 }
123 elsif ($op eq 'delete-branch-cat') {
124     my $categorycode  = $input->param('categorycode');
125     if ($branch eq "*") {
126         if ($categorycode eq "*") {
127             Koha::CirculationRules->set_rules(
128                 {
129                     branchcode   => undef,
130                     categorycode => undef,
131                     rules        => {
132                         max_holds                      => undef,
133                         patron_maxissueqty             => undef,
134                         patron_maxonsiteissueqty       => undef,
135                     }
136                 }
137             );
138             Koha::CirculationRules->set_rules(
139                 {
140                     branchcode   => undef,
141                     itemtype     => undef,
142                     rules        => {
143                         holdallowed             => undef,
144                         hold_fulfillment_policy => undef,
145                         returnbranch            => undef,
146                     }
147                 }
148             );
149         } else {
150             Koha::CirculationRules->set_rules(
151                 {
152                     categorycode => $categorycode,
153                     branchcode   => undef,
154                     rules        => {
155                         max_holds                => undef,
156                         patron_maxissueqty       => undef,
157                         patron_maxonsiteissueqty => undef,
158                     }
159                 }
160             );
161         }
162     } elsif ($categorycode eq "*") {
163         Koha::CirculationRules->set_rules(
164             {
165                 branchcode   => $branch,
166                 categorycode => undef,
167                 rules        => {
168                     max_holds                => undef,
169                     patron_maxissueqty       => undef,
170                     patron_maxonsiteissueqty => undef,
171                 }
172             }
173         );
174         Koha::CirculationRules->set_rules(
175             {
176                 branchcode   => $branch,
177                 itemtype     => undef,
178                 rules        => {
179                     holdallowed             => undef,
180                     hold_fulfillment_policy => undef,
181                     returnbranch            => undef,
182                 }
183             }
184         );
185     } else {
186         Koha::CirculationRules->set_rules(
187             {
188                 categorycode => $categorycode,
189                 branchcode   => $branch,
190                 rules        => {
191                     max_holds         => undef,
192                     patron_maxissueqty       => undef,
193                     patron_maxonsiteissueqty => undef,
194                 }
195             }
196         );
197     }
198 }
199 elsif ($op eq 'delete-branch-item') {
200     my $itemtype  = $input->param('itemtype');
201     if ($branch eq "*") {
202         if ($itemtype eq "*") {
203             Koha::CirculationRules->set_rules(
204                 {
205                     branchcode   => undef,
206                     itemtype     => undef,
207                     rules        => {
208                         holdallowed             => undef,
209                         hold_fulfillment_policy => undef,
210                         returnbranch            => undef,
211                     }
212                 }
213             );
214         } else {
215             Koha::CirculationRules->set_rules(
216                 {
217                     branchcode   => undef,
218                     itemtype     => $itemtype,
219                     rules        => {
220                         holdallowed             => undef,
221                         hold_fulfillment_policy => undef,
222                         returnbranch            => undef,
223                     }
224                 }
225             );
226         }
227     } elsif ($itemtype eq "*") {
228         Koha::CirculationRules->set_rules(
229             {
230                 branchcode   => $branch,
231                 itemtype     => undef,
232                 rules        => {
233                     holdallowed             => undef,
234                     hold_fulfillment_policy => undef,
235                     returnbranch            => undef,
236                 }
237             }
238         );
239     } else {
240         Koha::CirculationRules->set_rules(
241             {
242                 branchcode   => $branch,
243                 itemtype     => $itemtype,
244                 rules        => {
245                     holdallowed             => undef,
246                     hold_fulfillment_policy => undef,
247                     returnbranch            => undef,
248                 }
249             }
250         );
251     }
252 }
253 # save the values entered
254 elsif ($op eq 'add') {
255     my $br = $branch; # branch
256     my $bor  = $input->param('categorycode'); # borrower category
257     my $itemtype  = $input->param('itemtype');     # item type
258     my $fine = $input->param('fine');
259     my $finedays     = $input->param('finedays');
260     my $maxsuspensiondays = $input->param('maxsuspensiondays') || q{};
261     my $suspension_chargeperiod = $input->param('suspension_chargeperiod') || 1;
262     my $firstremind  = $input->param('firstremind');
263     my $chargeperiod = $input->param('chargeperiod');
264     my $chargeperiod_charge_at = $input->param('chargeperiod_charge_at');
265     my $maxissueqty = strip_non_numeric( scalar $input->param('maxissueqty') );
266     my $maxonsiteissueqty = strip_non_numeric( scalar $input->param('maxonsiteissueqty') );
267     my $renewalsallowed  = $input->param('renewalsallowed');
268     my $unseen_renewals_allowed  = defined $input->param('unseen_renewals_allowed') ? strip_non_numeric( scalar $input->param('unseen_renewals_allowed') ) : q{};
269     my $renewalperiod   = $input->param('renewalperiod');
270     my $norenewalbefore = $input->param('norenewalbefore');
271     $norenewalbefore = q{} if $norenewalbefore =~ /^\s*$/;
272     my $noautorenewalbefore = $input->param('noautorenewalbefore');
273     $noautorenewalbefore = q{} if $noautorenewalbefore =~ /^\s*$/;
274     my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
275     my $no_auto_renewal_after = $input->param('no_auto_renewal_after');
276     $no_auto_renewal_after = q{} if $no_auto_renewal_after =~ /^\s*$/;
277     my $no_auto_renewal_after_hard_limit = $input->param('no_auto_renewal_after_hard_limit') || q{};
278     my $reservesallowed  = strip_non_numeric( scalar $input->param('reservesallowed') );
279     my $holds_per_record = strip_non_numeric( scalar $input->param('holds_per_record') );
280     my $holds_per_day    = strip_non_numeric( scalar $input->param('holds_per_day') );
281     my $onshelfholds     = $input->param('onshelfholds') || 0;
282     my $issuelength  = $input->param('issuelength') || 0;
283     my $daysmode = $input->param('daysmode');
284     my $lengthunit  = $input->param('lengthunit');
285     my $hardduedate = $input->param('hardduedate') || q{};
286     my $hardduedatecompare = $input->param('hardduedatecompare');
287     my $rentaldiscount = $input->param('rentaldiscount') || 0;
288     my $opacitemholds = $input->param('opacitemholds') || 0;
289     my $article_requests = $input->param('article_requests') || 'no';
290     my $overduefinescap = $input->param('overduefinescap')
291         && ( $input->param('overduefinescap') + 0 ) > 0 ? sprintf( "%.02f", $input->param('overduefinescap') ) : q{};
292     my $cap_fine_to_replacement_price = ($input->param('cap_fine_to_replacement_price') || q{}) eq 'on';
293     my $note = $input->param('note');
294     my $decreaseloanholds = $input->param('decreaseloanholds') || q{};
295     my $recalls_allowed = $input->param('recalls_allowed');
296     my $recalls_per_record = $input->param('recalls_per_record');
297     my $on_shelf_recalls = $input->param('on_shelf_recalls');
298     my $recall_due_date_interval = $input->param('recall_due_date_interval');
299     my $recall_overdue_fine = $input->param('recall_overdue_fine');
300     my $recall_shelf_time = $input->param('recall_shelf_time');
301     my $holds_pickup_period = strip_non_numeric( scalar $input->param('holds_pickup_period') );
302
303     my $rules = {
304         maxissueqty                          => $maxissueqty,
305             maxonsiteissueqty                => $maxonsiteissueqty,
306             rentaldiscount                   => $rentaldiscount,
307             fine                             => $fine,
308             finedays                         => $finedays,
309             maxsuspensiondays                => $maxsuspensiondays,
310             suspension_chargeperiod          => $suspension_chargeperiod,
311             firstremind                      => $firstremind,
312             chargeperiod                     => $chargeperiod,
313             chargeperiod_charge_at           => $chargeperiod_charge_at,
314             issuelength                      => $issuelength,
315             daysmode                         => $daysmode,
316             lengthunit                       => $lengthunit,
317             hardduedate                      => $hardduedate,
318             hardduedatecompare               => $hardduedatecompare,
319             renewalsallowed                  => $renewalsallowed,
320             unseen_renewals_allowed          => $unseen_renewals_allowed,
321             renewalperiod                    => $renewalperiod,
322             norenewalbefore                  => $norenewalbefore,
323             noautorenewalbefore              => $noautorenewalbefore,
324             auto_renew                       => $auto_renew,
325             no_auto_renewal_after            => $no_auto_renewal_after,
326             no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
327             onshelfholds                     => $onshelfholds,
328             opacitemholds                    => $opacitemholds,
329             overduefinescap                  => $overduefinescap,
330             cap_fine_to_replacement_price    => $cap_fine_to_replacement_price,
331             article_requests                 => $article_requests,
332             note                             => $note,
333             decreaseloanholds                => $decreaseloanholds,
334             recalls_allowed                  => $recalls_allowed,
335             recalls_per_record               => $recalls_per_record,
336             on_shelf_recalls                 => $on_shelf_recalls,
337             recall_due_date_interval         => $recall_due_date_interval,
338             recall_overdue_fine              => $recall_overdue_fine,
339             recall_shelf_time                => $recall_shelf_time,
340             holds_pickup_period              => $holds_pickup_period,
341     };
342
343     Koha::CirculationRules->set_rules(
344         {
345             categorycode => $bor eq '*' ? undef : $bor,
346             itemtype     => $itemtype eq '*' ? undef : $itemtype,
347             branchcode   => $br eq '*' ? undef : $br,
348             rules        => $rules,
349         }
350     );
351
352 }
353 elsif ($op eq "set-branch-defaults") {
354     my $categorycode  = $input->param('categorycode');
355     my $patron_maxissueqty = strip_non_numeric( scalar $input->param('patron_maxissueqty') );
356     my $patron_maxonsiteissueqty = $input->param('patron_maxonsiteissueqty');
357     $patron_maxonsiteissueqty = strip_non_numeric($patron_maxonsiteissueqty);
358     my $holdallowed   = $input->param('holdallowed');
359     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
360     my $returnbranch  = $input->param('returnbranch');
361     my $max_holds = strip_non_numeric( scalar $input->param('max_holds') );
362
363     if ($branch eq "*") {
364         Koha::CirculationRules->set_rules(
365             {
366                 itemtype     => undef,
367                 branchcode   => undef,
368                 rules        => {
369                     holdallowed             => $holdallowed,
370                     hold_fulfillment_policy => $hold_fulfillment_policy,
371                     returnbranch            => $returnbranch,
372                 }
373             }
374         );
375         Koha::CirculationRules->set_rules(
376             {
377                 categorycode => undef,
378                 branchcode   => undef,
379                 rules        => {
380                     patron_maxissueqty             => $patron_maxissueqty,
381                     patron_maxonsiteissueqty       => $patron_maxonsiteissueqty,
382                 }
383             }
384         );
385     } else {
386         Koha::CirculationRules->set_rules(
387             {
388                 itemtype     => undef,
389                 branchcode   => $branch,
390                 rules        => {
391                     holdallowed             => $holdallowed,
392                     hold_fulfillment_policy => $hold_fulfillment_policy,
393                     returnbranch            => $returnbranch,
394                 }
395             }
396         );
397         Koha::CirculationRules->set_rules(
398             {
399                 categorycode => undef,
400                 branchcode   => $branch,
401                 rules        => {
402                     patron_maxissueqty             => $patron_maxissueqty,
403                     patron_maxonsiteissueqty       => $patron_maxonsiteissueqty,
404                 }
405             }
406         );
407     }
408     Koha::CirculationRules->set_rule(
409         {
410             branchcode   => $branch,
411             categorycode => undef,
412             rule_name    => 'max_holds',
413             rule_value   => $max_holds,
414         }
415     );
416 }
417 elsif ($op eq "add-branch-cat") {
418     my $categorycode  = $input->param('categorycode');
419     my $patron_maxissueqty = strip_non_numeric( scalar $input->param('patron_maxissueqty') );
420     my $patron_maxonsiteissueqty = $input->param('patron_maxonsiteissueqty');
421     $patron_maxonsiteissueqty = strip_non_numeric($patron_maxonsiteissueqty);
422     my $max_holds = $input->param('max_holds');
423     $max_holds = strip_non_numeric($max_holds);
424
425     if ($branch eq "*") {
426         if ($categorycode eq "*") {
427             Koha::CirculationRules->set_rules(
428                 {
429                     categorycode => undef,
430                     branchcode   => undef,
431                     rules        => {
432                         max_holds         => $max_holds,
433                         patron_maxissueqty       => $patron_maxissueqty,
434                         patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
435                     }
436                 }
437             );
438         } else {
439             Koha::CirculationRules->set_rules(
440                 {
441                     categorycode => $categorycode,
442                     branchcode   => undef,
443                     rules        => {
444                         max_holds         => $max_holds,
445                         patron_maxissueqty       => $patron_maxissueqty,
446                         patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
447                     }
448                 }
449             );
450         }
451     } elsif ($categorycode eq "*") {
452         Koha::CirculationRules->set_rules(
453             {
454                 categorycode => undef,
455                 branchcode   => $branch,
456                 rules        => {
457                     max_holds         => $max_holds,
458                     patron_maxissueqty       => $patron_maxissueqty,
459                     patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
460                 }
461             }
462         );
463     } else {
464         Koha::CirculationRules->set_rules(
465             {
466                 categorycode => $categorycode,
467                 branchcode   => $branch,
468                 rules        => {
469                     max_holds         => $max_holds,
470                     patron_maxissueqty       => $patron_maxissueqty,
471                     patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
472                 }
473             }
474         );
475     }
476 }
477 elsif ( $op eq "add-open-article-requests-limit" ) {
478     my $categorycode                = $input->param('categorycode');
479     my $open_article_requests_limit = strip_non_numeric( scalar $input->param('open_article_requests_limit') );
480
481     Koha::Exception->throw("No value passed for article request limit")
482       if not defined $open_article_requests_limit # There is a JS check for that
483       || $open_article_requests_limit eq q{};
484
485     if ( $branch eq "*" ) {
486         if ( $categorycode eq "*" ) {
487             Koha::CirculationRules->set_rules(
488                 {   categorycode => undef,
489                     branchcode   => undef,
490                     rules        => { open_article_requests_limit => $open_article_requests_limit, }
491                 }
492             );
493         } else {
494             Koha::CirculationRules->set_rules(
495                 {   categorycode => $categorycode,
496                     branchcode   => undef,
497                     rules        => { open_article_requests_limit => $open_article_requests_limit, }
498                 }
499             );
500         }
501     } elsif ( $categorycode eq "*" ) {
502         Koha::CirculationRules->set_rules(
503             {   categorycode => undef,
504                 branchcode   => $branch,
505                 rules        => { open_article_requests_limit => $open_article_requests_limit, }
506             }
507         );
508     } else {
509         Koha::CirculationRules->set_rules(
510             {   categorycode => $categorycode,
511                 branchcode   => $branch,
512                 rules        => { open_article_requests_limit => $open_article_requests_limit, }
513             }
514         );
515     }
516 } elsif ( $op eq 'del-open-article-requests-limit' ) {
517     my $categorycode = $input->param('categorycode');
518     if ( $branch eq "*" ) {
519         if ( $categorycode eq "*" ) {
520             Koha::CirculationRules->set_rules(
521                 {   branchcode   => undef,
522                     categorycode => undef,
523                     rules        => { open_article_requests_limit => undef, }
524                 }
525             );
526         } else {
527             Koha::CirculationRules->set_rules(
528                 {   categorycode => $categorycode,
529                     branchcode   => undef,
530                     rules        => { open_article_requests_limit => undef, }
531                 }
532             );
533         }
534     } elsif ( $categorycode eq "*" ) {
535         Koha::CirculationRules->set_rules(
536             {   branchcode   => $branch,
537                 categorycode => undef,
538                 rules        => { open_article_requests_limit => undef, }
539             }
540         );
541     } else {
542         Koha::CirculationRules->set_rules(
543             {   categorycode => $categorycode,
544                 branchcode   => $branch,
545                 rules        => { open_article_requests_limit => undef, }
546             }
547         );
548     }
549 }
550 elsif ( $op eq "set-article-request-fee" ) {
551
552     my $category = $input->param('article_request_fee_category');
553     my $fee      = strip_non_numeric( scalar $input->param('article_request_fee') );
554
555     Koha::Exception->throw("No value passed for article request fee")
556       if not defined $fee # There is a JS check for that
557       || $fee eq q{};
558
559     Koha::CirculationRules->set_rules(
560         {   categorycode => ( $category  eq '*' ) ? undef : $category,
561             branchcode   => ( $branch    eq '*' ) ? undef : $branch,
562             rules        => { article_request_fee => $fee },
563         }
564     );
565
566 } elsif ( $op eq 'del-article-request-fee' ) {
567
568     my $category  = $input->param('article_request_fee_category');
569
570     Koha::CirculationRules->set_rules(
571         {   categorycode => ( $category eq  '*' ) ? undef : $category,
572             branchcode   => ( $branch eq    '*' ) ? undef : $branch,
573             rules        => { article_request_fee => undef },
574         }
575     );
576 }
577 elsif ($op eq "add-branch-item") {
578     my $itemtype                = $input->param('itemtype');
579     my $holdallowed             = $input->param('holdallowed');
580     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
581     my $returnbranch            = $input->param('returnbranch');
582
583     if ($branch eq "*") {
584         if ($itemtype eq "*") {
585             Koha::CirculationRules->set_rules(
586                 {
587                     itemtype     => undef,
588                     branchcode   => undef,
589                     rules        => {
590                         holdallowed             => $holdallowed,
591                         hold_fulfillment_policy => $hold_fulfillment_policy,
592                         returnbranch            => $returnbranch,
593                     }
594                 }
595             );
596         } else {
597             Koha::CirculationRules->set_rules(
598                 {
599                     itemtype     => $itemtype,
600                     branchcode   => undef,
601                     rules        => {
602                         holdallowed             => $holdallowed,
603                         hold_fulfillment_policy => $hold_fulfillment_policy,
604                         returnbranch            => $returnbranch,
605                     }
606                 }
607             );
608         }
609     } elsif ($itemtype eq "*") {
610             Koha::CirculationRules->set_rules(
611                 {
612                     itemtype     => undef,
613                     branchcode   => $branch,
614                     rules        => {
615                         holdallowed             => $holdallowed,
616                         hold_fulfillment_policy => $hold_fulfillment_policy,
617                         returnbranch            => $returnbranch,
618                     }
619                 }
620             );
621     } else {
622         Koha::CirculationRules->set_rules(
623             {
624                 itemtype     => $itemtype,
625                 branchcode   => $branch,
626                 rules        => {
627                     holdallowed             => $holdallowed,
628                     hold_fulfillment_policy => $hold_fulfillment_policy,
629                     returnbranch            => $returnbranch,
630                 }
631             }
632         );
633     }
634 }
635 elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) {
636
637     my $lostreturn = $input->param('lostreturn');
638
639     if ( $lostreturn eq '*' ) {
640         if ( $branch ne '*' ) {
641             # only do something for $lostreturn eq '*' if branch-specific
642             Koha::CirculationRules->set_rules(
643                 {
644                     branchcode   => $branch,
645                     rules        => {
646                         lostreturn => undef
647                     }
648                 }
649             );
650         }
651     } else {
652         Koha::CirculationRules->set_rules(
653             {
654                 branchcode   => $branch,
655                 rules        => {
656                     lostreturn => $lostreturn
657                 }
658             }
659         );
660     }
661
662     my $processingreturn = $input->param('processingreturn');
663
664     if ( $processingreturn eq '*' ) {
665         if ( $branch ne '*' ) {
666             # only do something for $processingreturn eq '*' if branch-specific
667             Koha::CirculationRules->set_rules(
668                 {
669                     branchcode   => $branch,
670                     rules        => {
671                         processingreturn => undef
672                     }
673                 }
674             );
675         }
676     } else {
677         Koha::CirculationRules->set_rules(
678             {
679                 branchcode   => $branch,
680                 rules        => {
681                     processingreturn => $processingreturn
682                 }
683             }
684         );
685     }
686 } elsif ( $op eq "set-waiting-hold-cancellation" ) {
687
688     my $category = $input->param('waiting_hold_cancellation_category');
689     my $itemtype = $input->param('waiting_hold_cancellation_itemtype');
690     my $policy   = strip_non_numeric( scalar $input->param('waiting_hold_cancellation_policy') )
691                     ? 1
692                     : 0;
693
694     Koha::Exception->throw("No value passed for waiting holds cancellation policy")
695       if not defined $policy # There is a JS check for that
696       || $policy eq '';
697
698     Koha::CirculationRules->set_rules(
699         {   categorycode => ( $category eq '*' ) ? undef : $category,
700             itemtype     => ( $itemtype eq '*' ) ? undef : $itemtype,
701             branchcode   => ( $branch   eq '*' ) ? undef : $branch,
702             rules        => { waiting_hold_cancellation => $policy },
703         }
704     );
705
706 } elsif ( $op eq 'del-waiting-hold-cancellation' ) {
707
708     my $category = $input->param('waiting_hold_cancellation_category');
709     my $itemtype = $input->param('waiting_hold_cancellation_itemtype');
710
711     Koha::CirculationRules->set_rules(
712         {   categorycode => ( $category eq '*' ) ? undef : $category,
713             itemtype     => ( $itemtype eq '*' ) ? undef : $itemtype,
714             branchcode   => ( $branch   eq '*' ) ? undef : $branch,
715             rules        => { waiting_hold_cancellation => undef },
716         }
717     );
718 }
719
720
721 my $refundLostItemFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'lostreturn' });
722 my $defaultLostItemFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'lostreturn' });
723 my $refundProcessingFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'processingreturn' });
724 my $defaultProcessingFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'processingreturn' });
725 $template->param(
726     refundLostItemFeeRule => $refundLostItemFeeRule,
727     defaultRefundRule     => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 'refund',
728     refundProcessingFeeRule => $refundProcessingFeeRule,
729     defaultProcessingRefundRule => $defaultProcessingFeeRule ? $defaultProcessingFeeRule->rule_value : 'refund',
730 );
731
732 my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] });
733
734 my $itemtypes = Koha::ItemTypes->search_with_localization;
735
736 my $humanbranch = ( $branch ne '*' ? $branch : undef );
737
738 my $all_rules = Koha::CirculationRules->search({ branchcode => $humanbranch });
739 my $definedbranch = $all_rules->count ? 1 : 0;
740
741 my $rules = {};
742 while ( my $r = $all_rules->next ) {
743     $r = $r->unblessed;
744     $rules->{ $r->{categorycode} // q{} }->{ $r->{itemtype} // q{} }->{ $r->{rule_name} } = $r->{rule_value};
745 }
746
747 $template->param(show_branch_cat_rule_form => 1);
748
749 $template->param(
750     patron_categories => $patron_categories,
751     itemtypeloop      => $itemtypes,
752     humanbranch       => $humanbranch,
753     current_branch    => $branch,
754     definedbranch     => $definedbranch,
755     all_rules         => $rules,
756 );
757 output_html_with_http_headers $input, $cookie, $template->output;
758
759 exit 0;
760
761 # sort by patron category, then item type, putting
762 # default entries at the bottom
763 sub by_category_and_itemtype {
764     unless (by_category($a, $b)) {
765         return by_itemtype($a, $b);
766     }
767 }
768
769 sub by_category {
770     my ($a, $b) = @_;
771     if ($a->{'default_humancategorycode'}) {
772         return ($b->{'default_humancategorycode'} ? 0 : 1);
773     } elsif ($b->{'default_humancategorycode'}) {
774         return -1;
775     } else {
776         return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
777     }
778 }
779
780 sub by_itemtype {
781     my ($a, $b) = @_;
782     if ($a->{default_translated_description}) {
783         return ($b->{'default_translated_description'} ? 0 : 1);
784     } elsif ($b->{'default_translated_description'}) {
785         return -1;
786     } else {
787         return lc $a->{'translated_description'} cmp lc $b->{'translated_description'};
788     }
789 }
790
791 sub strip_non_numeric {
792     my $string = shift;
793     $string =~ s/\s//g;
794     $string = q{} if $string !~ /^\d+/;
795     return $string;
796 }