Bug 19532: Database and installer stuff
[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::DateUtils qw( dt_from_string output_pref );
27 use Koha::Database;
28 use Koha::Logger;
29 use Koha::Libraries;
30 use Koha::CirculationRules;
31 use Koha::Patron::Categories;
32 use Koha::Caches;
33 use Koha::Patrons;
34
35 my $input = CGI->new;
36 my $dbh = C4::Context->dbh;
37
38 # my $flagsrequired;
39 # $flagsrequired->{circulation}=1;
40 my ($template, $loggedinuser, $cookie)
41     = get_template_and_user({template_name => "admin/smart-rules.tt",
42                             query => $input,
43                             type => "intranet",
44                             flagsrequired => {parameters => 'manage_circ_rules'},
45                             });
46
47 my $type=$input->param('type');
48
49 my $branch = $input->param('branch');
50 unless ( $branch ) {
51     if ( C4::Context->preference('DefaultToLoggedInLibraryCircRules') ) {
52         $branch = Koha::Libraries->search->count() == 1 ? undef : C4::Context::mybranch();
53     }
54     else {
55         $branch = C4::Context::only_my_library() ? ( C4::Context::mybranch() || '*' ) : '*';
56     }
57 }
58
59 my $logged_in_patron = Koha::Patrons->find( $loggedinuser );
60
61 my $can_edit_from_any_library = $logged_in_patron->has_permission( {parameters => 'manage_circ_rules_from_any_libraries' } );
62 $template->param( restricted_to_own_library => not $can_edit_from_any_library );
63 $branch = C4::Context::mybranch() unless $can_edit_from_any_library;
64
65 my $op = $input->param('op') || q{};
66 my $language = C4::Languages::getlanguage();
67
68 my $cache = Koha::Caches->get_instance;
69 $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY );
70
71 if ($op eq 'delete') {
72     my $itemtype     = $input->param('itemtype');
73     my $categorycode = $input->param('categorycode');
74
75     Koha::CirculationRules->set_rules(
76         {
77             categorycode => $categorycode eq '*' ? undef : $categorycode,
78             branchcode   => $branch eq '*' ? undef : $branch,
79             itemtype     => $itemtype eq '*' ? undef : $itemtype,
80             rules        => {
81                 maxissueqty                      => undef,
82                 maxonsiteissueqty                => undef,
83                 rentaldiscount                   => undef,
84                 fine                             => undef,
85                 finedays                         => undef,
86                 maxsuspensiondays                => undef,
87                 suspension_chargeperiod          => undef,
88                 firstremind                      => undef,
89                 chargeperiod                     => undef,
90                 chargeperiod_charge_at           => undef,
91                 issuelength                      => undef,
92                 daysmode                         => undef,
93                 lengthunit                       => undef,
94                 hardduedate                      => undef,
95                 hardduedatecompare               => undef,
96                 renewalsallowed                  => undef,
97                 unseen_renewals_allowed          => undef,
98                 renewalperiod                    => undef,
99                 norenewalbefore                  => 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             }
119         }
120     );
121 }
122 elsif ($op eq 'delete-branch-cat') {
123     my $categorycode  = $input->param('categorycode');
124     if ($branch eq "*") {
125         if ($categorycode eq "*") {
126             Koha::CirculationRules->set_rules(
127                 {
128                     branchcode   => undef,
129                     categorycode => undef,
130                     rules        => {
131                         max_holds                      => undef,
132                         patron_maxissueqty             => undef,
133                         patron_maxonsiteissueqty       => undef,
134                     }
135                 }
136             );
137             Koha::CirculationRules->set_rules(
138                 {
139                     branchcode   => undef,
140                     itemtype     => undef,
141                     rules        => {
142                         holdallowed             => undef,
143                         hold_fulfillment_policy => undef,
144                         returnbranch            => undef,
145                     }
146                 }
147             );
148         } else {
149             Koha::CirculationRules->set_rules(
150                 {
151                     categorycode => $categorycode,
152                     branchcode   => undef,
153                     rules        => {
154                         max_holds                => undef,
155                         patron_maxissueqty       => undef,
156                         patron_maxonsiteissueqty => undef,
157                     }
158                 }
159             );
160         }
161     } elsif ($categorycode eq "*") {
162         Koha::CirculationRules->set_rules(
163             {
164                 branchcode   => $branch,
165                 categorycode => undef,
166                 rules        => {
167                     max_holds                => undef,
168                     patron_maxissueqty       => undef,
169                     patron_maxonsiteissueqty => undef,
170                 }
171             }
172         );
173         Koha::CirculationRules->set_rules(
174             {
175                 branchcode   => $branch,
176                 itemtype     => undef,
177                 rules        => {
178                     holdallowed             => undef,
179                     hold_fulfillment_policy => undef,
180                     returnbranch            => undef,
181                 }
182             }
183         );
184     } else {
185         Koha::CirculationRules->set_rules(
186             {
187                 categorycode => $categorycode,
188                 branchcode   => $branch,
189                 rules        => {
190                     max_holds         => undef,
191                     patron_maxissueqty       => undef,
192                     patron_maxonsiteissueqty => undef,
193                 }
194             }
195         );
196     }
197 }
198 elsif ($op eq 'delete-branch-item') {
199     my $itemtype  = $input->param('itemtype');
200     if ($branch eq "*") {
201         if ($itemtype eq "*") {
202             Koha::CirculationRules->set_rules(
203                 {
204                     branchcode   => undef,
205                     itemtype     => undef,
206                     rules        => {
207                         holdallowed             => undef,
208                         hold_fulfillment_policy => undef,
209                         returnbranch            => undef,
210                     }
211                 }
212             );
213         } else {
214             Koha::CirculationRules->set_rules(
215                 {
216                     branchcode   => undef,
217                     itemtype     => $itemtype,
218                     rules        => {
219                         holdallowed             => undef,
220                         hold_fulfillment_policy => undef,
221                         returnbranch            => undef,
222                     }
223                 }
224             );
225         }
226     } elsif ($itemtype eq "*") {
227         Koha::CirculationRules->set_rules(
228             {
229                 branchcode   => $branch,
230                 itemtype     => undef,
231                 rules        => {
232                     holdallowed             => undef,
233                     hold_fulfillment_policy => undef,
234                     returnbranch            => undef,
235                 }
236             }
237         );
238     } else {
239         Koha::CirculationRules->set_rules(
240             {
241                 branchcode   => $branch,
242                 itemtype     => $itemtype,
243                 rules        => {
244                     holdallowed             => undef,
245                     hold_fulfillment_policy => undef,
246                     returnbranch            => undef,
247                 }
248             }
249         );
250     }
251 }
252 # save the values entered
253 elsif ($op eq 'add') {
254     my $br = $branch; # branch
255     my $bor  = $input->param('categorycode'); # borrower category
256     my $itemtype  = $input->param('itemtype');     # item type
257     my $fine = $input->param('fine');
258     my $finedays     = $input->param('finedays');
259     my $maxsuspensiondays = $input->param('maxsuspensiondays') || '';
260     my $suspension_chargeperiod = $input->param('suspension_chargeperiod') || 1;
261     my $firstremind  = $input->param('firstremind');
262     my $chargeperiod = $input->param('chargeperiod');
263     my $chargeperiod_charge_at = $input->param('chargeperiod_charge_at');
264     my $maxissueqty = strip_non_numeric( scalar $input->param('maxissueqty') );
265     my $maxonsiteissueqty = strip_non_numeric( scalar $input->param('maxonsiteissueqty') );
266     my $renewalsallowed  = $input->param('renewalsallowed');
267     my $unseen_renewals_allowed  = $input->param('unseen_renewals_allowed');
268     my $renewalperiod    = $input->param('renewalperiod');
269     my $norenewalbefore  = $input->param('norenewalbefore');
270     $norenewalbefore = '' if $norenewalbefore =~ /^\s*$/;
271     my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
272     my $no_auto_renewal_after = $input->param('no_auto_renewal_after');
273     $no_auto_renewal_after = '' if $no_auto_renewal_after =~ /^\s*$/;
274     my $no_auto_renewal_after_hard_limit = $input->param('no_auto_renewal_after_hard_limit') || '';
275     $no_auto_renewal_after_hard_limit = eval { dt_from_string( scalar $no_auto_renewal_after_hard_limit ) } if ( $no_auto_renewal_after_hard_limit );
276     $no_auto_renewal_after_hard_limit = output_pref( { dt => $no_auto_renewal_after_hard_limit, dateonly => 1, dateformat => 'iso' } ) if ( $no_auto_renewal_after_hard_limit );
277     my $reservesallowed  = strip_non_numeric( scalar $input->param('reservesallowed') );
278     my $holds_per_record = strip_non_numeric( scalar $input->param('holds_per_record') );
279     my $holds_per_day    = strip_non_numeric( scalar $input->param('holds_per_day') );
280     my $onshelfholds     = $input->param('onshelfholds') || 0;
281     my $issuelength  = $input->param('issuelength');
282     $issuelength = $issuelength eq q{} ? undef : $issuelength;
283     my $daysmode = $input->param('daysmode');
284     my $lengthunit  = $input->param('lengthunit');
285     my $hardduedate = $input->param('hardduedate') || undef;
286     $hardduedate = eval { dt_from_string( scalar $hardduedate ) } if ( $hardduedate );
287     $hardduedate = output_pref( { dt => $hardduedate, dateonly => 1, dateformat => 'iso' } ) if ( $hardduedate );
288     my $hardduedatecompare = $input->param('hardduedatecompare');
289     my $rentaldiscount = $input->param('rentaldiscount');
290     my $opacitemholds = $input->param('opacitemholds') || 0;
291     my $article_requests = $input->param('article_requests') || 'no';
292     my $overduefinescap = $input->param('overduefinescap') || '';
293     my $cap_fine_to_replacement_price = ($input->param('cap_fine_to_replacement_price') || '') eq 'on';
294     my $note = $input->param('note');
295     my $decreaseloanholds = $input->param('decreaseloanholds') || undef;
296     my $recalls_allowed = $input->param('recalls_allowed');
297     my $recalls_per_record = $input->param('recalls_per_record');
298     my $on_shelf_recalls = $input->param('on_shelf_recalls');
299     my $recall_due_date_interval = $input->param('recall_due_date_interval');
300     my $recall_overdue_fine = $input->param('recall_overdue_fine');
301     my $recall_shelf_time = $input->param('recall_shelf_time');
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         auto_renew                    => $auto_renew,
324         no_auto_renewal_after         => $no_auto_renewal_after,
325         no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
326         reservesallowed               => $reservesallowed,
327         holds_per_record              => $holds_per_record,
328         holds_per_day                 => $holds_per_day,
329         onshelfholds                  => $onshelfholds,
330         opacitemholds                 => $opacitemholds,
331         overduefinescap               => $overduefinescap,
332         cap_fine_to_replacement_price => $cap_fine_to_replacement_price,
333         article_requests              => $article_requests,
334         note                          => $note,
335         decreaseloanholds             => $decreaseloanholds,
336         recalls_allowed               => $recalls_allowed,
337         recalls_per_record            => $recalls_per_record,
338         on_shelf_recalls              => $on_shelf_recalls,
339         recall_due_date_interval      => $recall_due_date_interval,
340         recall_overdue_fine           => $recall_overdue_fine,
341         recall_shelf_time             => $recall_shelf_time,
342     };
343
344     Koha::CirculationRules->set_rules(
345         {
346             categorycode => $bor eq '*' ? undef : $bor,
347             itemtype     => $itemtype eq '*' ? undef : $itemtype,
348             branchcode   => $br eq '*' ? undef : $br,
349             rules        => $rules,
350         }
351     );
352
353 }
354 elsif ($op eq "set-branch-defaults") {
355     my $categorycode  = $input->param('categorycode');
356     my $patron_maxissueqty = strip_non_numeric( scalar $input->param('patron_maxissueqty') );
357     my $patron_maxonsiteissueqty = $input->param('patron_maxonsiteissueqty');
358     $patron_maxonsiteissueqty = strip_non_numeric($patron_maxonsiteissueqty);
359     my $holdallowed   = $input->param('holdallowed');
360     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
361     my $returnbranch  = $input->param('returnbranch');
362     my $max_holds = strip_non_numeric( scalar $input->param('max_holds') );
363
364     if ($branch eq "*") {
365         Koha::CirculationRules->set_rules(
366             {
367                 itemtype     => undef,
368                 branchcode   => undef,
369                 rules        => {
370                     holdallowed             => $holdallowed,
371                     hold_fulfillment_policy => $hold_fulfillment_policy,
372                     returnbranch            => $returnbranch,
373                 }
374             }
375         );
376         Koha::CirculationRules->set_rules(
377             {
378                 categorycode => undef,
379                 branchcode   => undef,
380                 rules        => {
381                     patron_maxissueqty             => $patron_maxissueqty,
382                     patron_maxonsiteissueqty       => $patron_maxonsiteissueqty,
383                 }
384             }
385         );
386     } else {
387         Koha::CirculationRules->set_rules(
388             {
389                 itemtype     => undef,
390                 branchcode   => $branch,
391                 rules        => {
392                     holdallowed             => $holdallowed,
393                     hold_fulfillment_policy => $hold_fulfillment_policy,
394                     returnbranch            => $returnbranch,
395                 }
396             }
397         );
398         Koha::CirculationRules->set_rules(
399             {
400                 categorycode => undef,
401                 branchcode   => $branch,
402                 rules        => {
403                     patron_maxissueqty             => $patron_maxissueqty,
404                     patron_maxonsiteissueqty       => $patron_maxonsiteissueqty,
405                 }
406             }
407         );
408     }
409     Koha::CirculationRules->set_rule(
410         {
411             branchcode   => $branch,
412             categorycode => undef,
413             rule_name    => 'max_holds',
414             rule_value   => $max_holds,
415         }
416     );
417 }
418 elsif ($op eq "add-branch-cat") {
419     my $categorycode  = $input->param('categorycode');
420     my $patron_maxissueqty = strip_non_numeric( scalar $input->param('patron_maxissueqty') );
421     my $patron_maxonsiteissueqty = $input->param('patron_maxonsiteissueqty');
422     $patron_maxonsiteissueqty = strip_non_numeric($patron_maxonsiteissueqty);
423     my $max_holds = $input->param('max_holds');
424     $max_holds =~ s/\s//g;
425     $max_holds = undef if $max_holds !~ /^\d+/;
426
427     if ($branch eq "*") {
428         if ($categorycode eq "*") {
429             Koha::CirculationRules->set_rules(
430                 {
431                     categorycode => undef,
432                     branchcode   => undef,
433                     rules        => {
434                         max_holds         => $max_holds,
435                         patron_maxissueqty       => $patron_maxissueqty,
436                         patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
437                     }
438                 }
439             );
440         } else {
441             Koha::CirculationRules->set_rules(
442                 {
443                     categorycode => $categorycode,
444                     branchcode   => undef,
445                     rules        => {
446                         max_holds         => $max_holds,
447                         patron_maxissueqty       => $patron_maxissueqty,
448                         patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
449                     }
450                 }
451             );
452         }
453     } elsif ($categorycode eq "*") {
454         Koha::CirculationRules->set_rules(
455             {
456                 categorycode => undef,
457                 branchcode   => $branch,
458                 rules        => {
459                     max_holds         => $max_holds,
460                     patron_maxissueqty       => $patron_maxissueqty,
461                     patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
462                 }
463             }
464         );
465     } else {
466         Koha::CirculationRules->set_rules(
467             {
468                 categorycode => $categorycode,
469                 branchcode   => $branch,
470                 rules        => {
471                     max_holds         => $max_holds,
472                     patron_maxissueqty       => $patron_maxissueqty,
473                     patron_maxonsiteissueqty => $patron_maxonsiteissueqty,
474                 }
475             }
476         );
477     }
478 }
479 elsif ( $op eq "add-open-article-requests-limit" ) {
480     my $categorycode                = $input->param('categorycode');
481     my $open_article_requests_limit = strip_non_numeric( scalar $input->param('open_article_requests_limit') );
482
483     Koha::Exception->throw("No value passed for article request limit")
484       if not defined $open_article_requests_limit # There is a JS check for that
485       || $open_article_requests_limit eq '';
486
487     if ( $branch eq "*" ) {
488         if ( $categorycode eq "*" ) {
489             Koha::CirculationRules->set_rules(
490                 {   categorycode => undef,
491                     branchcode   => undef,
492                     rules        => { open_article_requests_limit => $open_article_requests_limit, }
493                 }
494             );
495         } else {
496             Koha::CirculationRules->set_rules(
497                 {   categorycode => $categorycode,
498                     branchcode   => undef,
499                     rules        => { open_article_requests_limit => $open_article_requests_limit, }
500                 }
501             );
502         }
503     } elsif ( $categorycode eq "*" ) {
504         Koha::CirculationRules->set_rules(
505             {   categorycode => undef,
506                 branchcode   => $branch,
507                 rules        => { open_article_requests_limit => $open_article_requests_limit, }
508             }
509         );
510     } else {
511         Koha::CirculationRules->set_rules(
512             {   categorycode => $categorycode,
513                 branchcode   => $branch,
514                 rules        => { open_article_requests_limit => $open_article_requests_limit, }
515             }
516         );
517     }
518 } elsif ( $op eq 'del-open-article-requests-limit' ) {
519     my $categorycode = $input->param('categorycode');
520     if ( $branch eq "*" ) {
521         if ( $categorycode eq "*" ) {
522             Koha::CirculationRules->set_rules(
523                 {   branchcode   => undef,
524                     categorycode => undef,
525                     rules        => { open_article_requests_limit => undef, }
526                 }
527             );
528         } else {
529             Koha::CirculationRules->set_rules(
530                 {   categorycode => $categorycode,
531                     branchcode   => undef,
532                     rules        => { open_article_requests_limit => undef, }
533                 }
534             );
535         }
536     } elsif ( $categorycode eq "*" ) {
537         Koha::CirculationRules->set_rules(
538             {   branchcode   => $branch,
539                 categorycode => undef,
540                 rules        => { open_article_requests_limit => undef, }
541             }
542         );
543     } else {
544         Koha::CirculationRules->set_rules(
545             {   categorycode => $categorycode,
546                 branchcode   => $branch,
547                 rules        => { open_article_requests_limit => undef, }
548             }
549         );
550     }
551 }
552 elsif ( $op eq "set-article-request-fee" ) {
553
554     my $category = $input->param('article_request_fee_category');
555     my $fee      = strip_non_numeric( scalar $input->param('article_request_fee') );
556
557     Koha::Exception->throw("No value passed for article request fee")
558       if not defined $fee # There is a JS check for that
559       || $fee eq '';
560
561     Koha::CirculationRules->set_rules(
562         {   categorycode => ( $category  eq '*' ) ? undef : $category,
563             branchcode   => ( $branch    eq '*' ) ? undef : $branch,
564             rules        => { article_request_fee => $fee },
565         }
566     );
567
568 } elsif ( $op eq 'del-article-request-fee' ) {
569
570     my $category  = $input->param('article_request_fee_category');
571
572     Koha::CirculationRules->set_rules(
573         {   categorycode => ( $category eq  '*' ) ? undef : $category,
574             branchcode   => ( $branch eq    '*' ) ? undef : $branch,
575             rules        => { article_request_fee => undef },
576         }
577     );
578 }
579 elsif ($op eq "add-branch-item") {
580     my $itemtype                = $input->param('itemtype');
581     my $holdallowed             = $input->param('holdallowed');
582     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
583     my $returnbranch            = $input->param('returnbranch');
584
585     if ($branch eq "*") {
586         if ($itemtype eq "*") {
587             Koha::CirculationRules->set_rules(
588                 {
589                     itemtype     => undef,
590                     branchcode   => undef,
591                     rules        => {
592                         holdallowed             => $holdallowed,
593                         hold_fulfillment_policy => $hold_fulfillment_policy,
594                         returnbranch            => $returnbranch,
595                     }
596                 }
597             );
598         } else {
599             Koha::CirculationRules->set_rules(
600                 {
601                     itemtype     => $itemtype,
602                     branchcode   => undef,
603                     rules        => {
604                         holdallowed             => $holdallowed,
605                         hold_fulfillment_policy => $hold_fulfillment_policy,
606                         returnbranch            => $returnbranch,
607                     }
608                 }
609             );
610         }
611     } elsif ($itemtype eq "*") {
612             Koha::CirculationRules->set_rules(
613                 {
614                     itemtype     => undef,
615                     branchcode   => $branch,
616                     rules        => {
617                         holdallowed             => $holdallowed,
618                         hold_fulfillment_policy => $hold_fulfillment_policy,
619                         returnbranch            => $returnbranch,
620                     }
621                 }
622             );
623     } else {
624         Koha::CirculationRules->set_rules(
625             {
626                 itemtype     => $itemtype,
627                 branchcode   => $branch,
628                 rules        => {
629                     holdallowed             => $holdallowed,
630                     hold_fulfillment_policy => $hold_fulfillment_policy,
631                     returnbranch            => $returnbranch,
632                 }
633             }
634         );
635     }
636 }
637 elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) {
638
639     my $lostreturn = $input->param('lostreturn');
640
641     if ( $lostreturn eq '*' ) {
642         if ( $branch ne '*' ) {
643             # only do something for $lostreturn eq '*' if branch-specific
644             Koha::CirculationRules->set_rules(
645                 {
646                     branchcode   => $branch,
647                     rules        => {
648                         lostreturn => undef
649                     }
650                 }
651             );
652         }
653     } else {
654         Koha::CirculationRules->set_rules(
655             {
656                 branchcode   => $branch,
657                 rules        => {
658                     lostreturn => $lostreturn
659                 }
660             }
661         );
662     }
663 }
664
665 my $refundLostItemFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'lostreturn' });
666 my $defaultLostItemFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'lostreturn' });
667 $template->param(
668     refundLostItemFeeRule => $refundLostItemFeeRule,
669     defaultRefundRule     => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 'refund'
670 );
671
672 my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] });
673
674 my $itemtypes = Koha::ItemTypes->search_with_localization;
675
676 my $humanbranch = ( $branch ne '*' ? $branch : undef );
677
678 my $all_rules = Koha::CirculationRules->search({ branchcode => $humanbranch });
679 my $definedbranch = $all_rules->count ? 1 : 0;
680
681 my $rules = {};
682 while ( my $r = $all_rules->next ) {
683     $r = $r->unblessed;
684     $rules->{ $r->{categorycode} // '' }->{ $r->{itemtype} // '' }->{ $r->{rule_name} } = $r->{rule_value};
685 }
686
687 $template->param(show_branch_cat_rule_form => 1);
688
689 $template->param(
690     patron_categories => $patron_categories,
691     itemtypeloop      => $itemtypes,
692     humanbranch       => $humanbranch,
693     current_branch    => $branch,
694     definedbranch     => $definedbranch,
695     all_rules         => $rules,
696 );
697 output_html_with_http_headers $input, $cookie, $template->output;
698
699 exit 0;
700
701 # sort by patron category, then item type, putting
702 # default entries at the bottom
703 sub by_category_and_itemtype {
704     unless (by_category($a, $b)) {
705         return by_itemtype($a, $b);
706     }
707 }
708
709 sub by_category {
710     my ($a, $b) = @_;
711     if ($a->{'default_humancategorycode'}) {
712         return ($b->{'default_humancategorycode'} ? 0 : 1);
713     } elsif ($b->{'default_humancategorycode'}) {
714         return -1;
715     } else {
716         return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
717     }
718 }
719
720 sub by_itemtype {
721     my ($a, $b) = @_;
722     if ($a->{default_translated_description}) {
723         return ($b->{'default_translated_description'} ? 0 : 1);
724     } elsif ($b->{'default_translated_description'}) {
725         return -1;
726     } else {
727         return lc $a->{'translated_description'} cmp lc $b->{'translated_description'};
728     }
729 }
730
731 sub strip_non_numeric {
732     my $string = shift;
733     $string =~ s/\s//g;
734     $string = '' if $string !~ /^\d+/;
735     return $string;
736 }